C# 如何在使用backgroundWorker的过程中停止实施
所以,这段代码使用随机起始数获取递增数流的值。如果start1的值大于start2,我想用文本框显示对应的行,否则显示另一行 问题是我不能停止程序,直到给定的周期数不满足。按钮在植入过程中挂起。我理解这种情况发生的原因是一个循环。现在我试图用backgroundWorker停止它,但我得到了相同的结果,“取消”按钮以相同的方式挂起 我希望与位于backgroundWorker1\u ProgressChanged内的backgroundWorker一起使用的代码。我真的不太明白这里发生了什么。也许你能帮我找出我做错了什么:C# 如何在使用backgroundWorker的过程中停止实施,c#,loops,backgroundworker,cycle,C#,Loops,Backgroundworker,Cycle,所以,这段代码使用随机起始数获取递增数流的值。如果start1的值大于start2,我想用文本框显示对应的行,否则显示另一行 问题是我不能停止程序,直到给定的周期数不满足。按钮在植入过程中挂起。我理解这种情况发生的原因是一个循环。现在我试图用backgroundWorker停止它,但我得到了相同的结果,“取消”按钮以相同的方式挂起 我希望与位于backgroundWorker1\u 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可以做什么的好示例。基本上,您的代码只是休眠一点,然后报告进度,在另一个线程中几乎没有用处
添加1000 textBox1.AppendText后,您的backgroundWorker1_ProgressChanged相当繁重,因此可能需要一些时间
按钮在植入过程中挂起。我理解这种情况发生的原因是一个循环
当您在UI线程上考虑BeaBeWorks1Pro进程被执行时,无论您在取消上进行多少次点击,都不会被处理,直到BealWorkWork1PosirrsSechange返回。所有UI处理都必须由UI线程完成。应该指出的是,在此期间后台工作线程也被挂起,不幸的是,它是测试取消的代码的唯一部分。即使ReportProgress是异步的,您仍然需要UI线程处理cancel button click事件并将工作标记为CancellationPending
<> P>我建议你不要在后台进行一次报告,一步一步的改变,或者考虑报告将项目添加到文本框中作为批次。 这样,您就不会大量使用消息泵,应用程序的响应速度也会更快 将您的backgroundWorker1\u ProgressChangedobject发件人ProgressChangedEventArgs e更改为将批次用作: 由于您的ProgressChanged处理程序在每次ReportProgress调用中都忙于更新UI大约1000次,因此它将使用所有UI线程CPU时间,并且该线程将永远无法处理Cancel按钮,因为它已经太忙了 考虑到您使用的是BackgroundWorker,您应该在DoWork处理程序中移动大部分ProgressChanged,并在后台线程中删除睡眠 顺便说一句,你使用后台软件没有任何意义。UI线程应该尽可能少地执行任务,而后台线程应该尽可能多地执行任务。在您的情况下,在后台线程中睡眠是没有意义的,因为后台工作不依赖于所经过的时间 移动代码后,需要将数据发送回UI线程。但这很容易,因为ReportProgress的重载允许将任何.NET对象传递给UI线程,假设后台工作线程是从UI线程创建的,通常情况下就是这样。另一方面,您可以简单地将用户数据强制转换为适当的类型,并使用该信息将适当的文本附加到文本框中通过改进代码,您应该能够更快地处理数据。顺便说一下,还应该使用StringBuilder来构建字符串。事实上,它应该会对UI性能产生显著影响,因为您更新UI文本的次数会减少1000次。除了我的答案之外,您还可以查看该页面上的相关部分以获取有用的信息。显然,上面的实现非常糟糕,并且对BackgroundWorker的工作方式理解很差。我的性能非常差,不确定该怎么做,如果我将代码放在backgroundWorker1上,而不是放在worker上。ReportProgress就这样,我很怀疑这一点。你认为什么会更快?一条追加文本还是1000条追加文本?大部分CPU时间都花在AppendText上,即使调用堆栈来自另一个线程后台工作程序的ReportProgress
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());