【发布时间】:2014-07-18 21:25:56
【问题描述】:
我在我的应用程序中使用 BackgroundWorker。当 Backgroundworker 仍然很忙时,我可以显示进度条的变化。但是,当我使用 AutoResetEvent 等到 Backgroundworker 完成时,我没有看到进度条发生变化。有没有另一种方法,我可以等待 BackgroundWorker 完成并显示进度条更改?我对 C# 框架和编程很陌生。
private AutoResetEvent _resetEvent = new AutoResetEvent(false);
private void InitializeBackgroundWorker()
{
parserBackgroundWorker.DoWork +=
new DoWorkEventHandler(parserBackgroundWorker_DoWork);
parserBackgroundWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(
parserBackgroundWorker_RunWorkerCompleted);
parserBackgroundWorker.ProgressChanged +=
new ProgressChangedEventHandler(
parserBackgroundWorker_ProgressChanged);
parserBackgroundWorker.WorkerReportsProgress = true;
parserBackgroundWorker.WorkerSupportsCancellation = true;
}
private void parserBackgroundWorker_DoWork(object sender,
DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
parser.Parse((SegmentFile)e.Argument);
_resetEvent.Set();
}
// This event handler deals with the results of the
// background operation.
private void parserBackgroundWorker_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled
// flag may not have been set, even though
// CancelAsync was called.
//resultLabel.Text = "Canceled";
}
else
{
// Finally, handle the case where the operation
// succeeded.
//resultLabel.Text = e.Result.ToString();
}
}
// This event handler updates the progress bar.
private void parserBackgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
ProgressBar1.Value = e.ProgressPercentage;
}
parserBackgroundWorker.RunWorkerAsync(selectedSegFile);
// when I comment this code I do see the progress bar change as the thread is doing the work.
_resetEvent.WaitOne();
【问题讨论】:
-
为什么要阻塞 UI 线程?您应该放置 _resetEvent.WaitOne(); 之后的代码。在 RunWorkerCompleted()
-
正如 Dmitry 解释的那样,您在调用
WaitOne时阻塞了 UI 线程。您的BackgroundWorker正在更新进度条的Value属性并使其无效,但是应该执行控件实际绘制的线程被阻塞等待事件。 -
我在多个地方都使用了这个 backgroundworker,所以我无法将代码放在 RunWorkerCompleted() 中。
-
@savi:我不太了解您的程序是如何组织的,但是您可以轻松地从任意位置附加和分离不同的
RunWorkerCompleted事件处理程序。或者,您可以有一个处理程序,它在不同的情况下会有不同的行为。您当然不想做的事情是阻塞 UI 线程(因为在这种情况下您根本不需要后台工作人员)。 -
你能举个例子“但是你可以很容易地从任何你想要的地方附加和分离不同的 RunWorkerCompleted 事件处理程序。或者,你可以有一个处理程序,它在不同的情况下会有不同的行为。”?
标签: c# wpf progress-bar backgroundworker autoresetevent