C# 为什么在工作完成后才调用BackgroundWorker.ProgressChanged?
之前对类似问题的回答建议用户,他们可能没有足够的时间花在工作上,无法打电话给ProgressChanged。但是我的计算很长——它们至少需要30秒来计算环路内每个站点的计算值。C# 为什么在工作完成后才调用BackgroundWorker.ProgressChanged?,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,之前对类似问题的回答建议用户,他们可能没有足够的时间花在工作上,无法打电话给ProgressChanged。但是我的计算很长——它们至少需要30秒来计算环路内每个站点的计算值。 通过在调试器中单步执行代码,DoWork确实会被调用并调用ReportProgress。但是,即使当DoWork由于循环完成而完成时,也不会立即调用RunWorkerCompleted。 以下是事件的顺序: 调用DoWork 当isBusy为true时,主线程继续循环 尽管DoWork完成了循环,但它并没有完成,但主线程
通过在调试器中单步执行代码,DoWork确实会被调用并调用ReportProgress。但是,即使当DoWork由于循环完成而完成时,也不会立即调用RunWorkerCompleted。 以下是事件的顺序:
Boolean isBusy = true;
// setting up a BackgroundWorker because the screen needs time to redraw
BackgroundWorker bgw = new BackgroundWorker();
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.DoWork += delegate
{
do
{
isOK = CreateAverageRatingsComparisonCSV(stationIndex, out stationTitle);
stationIndex++;
count++;
int percent = (int)(100 * count / numStations);
if (percent == 0)
percent = 1;
bgw.ReportProgress(percent, stationTitle);
} while (isOK && stationTitle.Length > 0);
};
bgw.RunWorkerCompleted += delegate
{
isBusy = false;
};
bgw.ProgressChanged += new ProgressChangedEventHandler(bgworker_ProgressChanged);
bgw.RunWorkerAsync();
// wait a 1/2 second at a time for BGW to finish
while (bgw.IsBusy && isBusy)
{
System.Threading.Thread.Sleep(500);
}
bgw.Dispose();
//////////////////////////////////////////
private void bgworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//display stationTitle
SetStatusBar("Message", (string)e.UserState);
}//END
在BGW运行时,您正在阻止UI线程。除了
DoWork
,所有BGW的事件处理程序都被封送到UI线程。因为它被阻塞了,所以他们只是坐在消息队列中无所事事,直到您的工作人员结束
如果您只是让UI线程在完成之前一直处于阻塞状态,那么使用BGW的整个目的就失败了。你最好只是在UI线程上做正确的工作
您应该删除在工作线程工作时阻止UI线程的代码。如果要在工作线程完成时在UI线程中执行代码,请使用
RunWorkerCompleted
事件。是否尝试在ProgressChanged事件中仅设置一个断点并让代码运行?是否可能是SetStatusBar代码中的问题?是什么代码阻塞了UI线程?它是带有sleep命令的while循环吗?或者您的意思是运行的BGW被封送到被阻止的UI线程?阻止UI线程的代码是什么。@DianaCook当BGW未完成时,有UI线程睡眠的代码是阻止UI线程的代码。