我需要生成n个随机字符串,这个过程可能需要一段时间并阻塞主线程UI。为避免这种情况,让用户在进程运行时使用该程序,我决定使用backGroundWorker
。但它并没有很好地工作,主线程仍然被阻止。在我的DoWork
事件中,我有类似的事情:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// using Invoke because I change value of some controls, e.g, ListView, labels and a progressbar
this.Invoke((Action)delegate
{
for (int i = 0; i < nSteps; ++i)
{
string s = getnStr();
// ...
int progress = (int)(100.0 / nSteps * (i + 1));
backgroundWorker1.ReportProgress(progress);
}
});
}
即使我在循环中调用ReportProgress()
,但进度条仅在循环完成时更改其值。
为什么会发生这种情况?我该如何解决这个问题?
答案 0 :(得分:3)
另一个答案解释了你所看到的行为。请先阅读。以下是解决此问题的方法:
BackgroundWorker
已过时,因为我们现在有Task
和await
。它自动化很多。您的代码可能应如下所示:
//In the button click handler:
for (int i = 0; i < nSteps; ++i)
{
await DoSomeWorkAsync();
int progress = (int)(100.0 / nSteps * (i + 1));
SetProgressBarValue(progress);
}
真的是这一切。您需要确保DoSomeWorkAsync
不会阻止。它必须返回Task
。