因此此代码采用具有随机起始编号的递增编号流的值。如果start1的值更大,则start2我想用文本框显示相应的行,否则显示另一行。
问题是,直到不满足给定的循环数,我才能停止程序。按钮仅在植入过程中挂起。我了解发生这种情况的原因是循环。现在,我尝试使用backgroundWorker停止它,但得到相同的结果,取消按钮的挂起方式相同。
我想与位于backgroundWorker1_ProgressChanged内的backgroundWorker一起使用的代码。我真的不太明白这里发生了什么。也许您可以帮助我找出我做错了什么:
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace XX_8_0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
private void startAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
backgroundWorker1.CancelAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var random = new Random();
var start1 = random.Next(0, 100);
var start2 = random.Next(0, 100);
var incrementor1 = start1 > 50 ? -1 : 1;
var incrementor2 = start2 > 50 ? -1 : 1;
var cV1 = start1;
var cV2 = start2;
for (var i = 0; i < 1000; i++)
{
if (cV1 == 101) incrementor1 = -1;
if (cV1 == 0) incrementor1 = 1;
if (cV2 == 101) incrementor2 = -1;
if (cV2 == 0) incrementor2 = 1;
if (cV1 > cV2)
{
textBox1.AppendText("ID: (" + i + ") CV1: (1): [" + cV1 + "] CV2: (0) [" + cV2 + "]\n");
}
else
{
textBox1.AppendText("ID: (" + i + ") CV1: (0): [" + cV1 + "] CV2: (1) [" + cV2 + "]\n");
}
cV1 += incrementor1;
cV2 += incrementor2;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}
}
}
最佳答案
注意:我认为您的例子可能不是BackgroundWorker
可以做的一个很好的例子。本质上,您的代码只是睡了一会儿然后报告进度,在另一个线程中几乎没有用。
您的backgroundWorker1_ProgressChanged
很重,添加了1000个textBox1.AppendText()
,因此可能需要一些时间。
按钮仅在植入过程中挂起。我了解发生这种情况的原因是循环。
当您考虑在用户界面线程上执行backgroundWorker1_ProgressChanged
时,无论您点击多少次取消,直到backgroundWorker1_ProgressChanged
返回之前,都不会对其进行处理。所有UI处理都必须由UI线程完成。应该指出的是,后台工作线程在这段时间内也被挂起,不幸的是,它是代码中测试取消的唯一部分。即使ReportProgress
不同步,您仍然需要UI线程来处理“取消”按钮的单击事件并将工作标记为CancellationPending
。
我建议您不要一次报告backgroundWorker1_ProgressChanged
太多,或者考虑考虑批量报告向textBox1
添加项目。
这样一来,您就不会淹没消息泵,并且您的应用程序将具有更高的响应速度。
更改您的backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
以将批处理用作:
var builder = new StringBuilder();
for (var i = 0; i < 1000; i++)
{
if (cV1 == 101) incrementor1 = -1;
if (cV1 == 0) incrementor1 = 1;
if (cV2 == 101) incrementor2 = -1;
if (cV2 == 0) incrementor2 = 1;
if (cV1 > cV2)
{
builder.Append("ID: (" + i + ") CV1: (1): [" + cV1 + "] CV2: (0) [" + cV2 + "]\n");
}
else
{
builder.Append("ID: (" + i + ") CV1: (0): [" + cV1 + "] CV2: (1) [" + cV2 + "]\n");
}
cV1 += incrementor1;
cV2 += incrementor2;
}
textbox1.AppendText(builder.ToString());
关于c# - 如何使用backgroundWorker在过程中停止实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39339792/