为什么BackgroundWorker不需要在ProgressChanged事件处理程序中调用?

时间:2012-08-25 11:52:25

标签: c# .net backgroundworker

由于ProgressChanged事件处理程序是从DoWork事件处理程序中的某个地方引发的,因此它们不应该在异步操作线程上调用,DoWork也运行它,而不是UI线程,因此需要调用或BeginInvoke来操纵控件?

我的猜测是在ReportProgress方法中发生了一些魔法,但它怎么知道,哪一个是调用ProgressChanged事件处理程序的正确线程?

1 个答案:

答案 0 :(得分:6)

当您致电RunWorkerAsync时,BackgroundWorker会在内部创建与当前同步上下文关联的新AsyncOperation,并通过AsyncOperationManager.SynchronizationContext静态属性检索。

此同步上下文将是从SynchronizationContext派生的类的实例。特定类型取决于应用程序使用的同步模型提供程序。如果您运行的是Windows Forms,则为WindowsFormsSynchronizationContext;在WPF;它将是DispatcherSynchronizationContext

当您随后在后台线程上调用ReportProgress时,BackgroundWorker会在上述SynchronizationContext实例内部调用Post,从而异步地将操作分派给关联的线程

在Windows窗体中,这是作为Control.BeginInvoke调用实现的;在WPF上,它变为Dispatcher.BeginInvoke电话。