4

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

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

4

1 回答 1

6

当您调用RunWorkerAsync时,BackgroundWorker内部会创建一个AsyncOperation与当前同步上下文关联的新上下文,如通过AsyncOperationManager.SynchronizationContext静态属性检索的那样。

此同步上下文将是派生自 的类的实例SynchronizationContext。具体类型取决于您的应用程序使用的同步模型提供程序。如果您正在运行 Windows 窗体,它会是WindowsFormsSynchronizationContext;在 WPF 上;会的DispatcherSynchronizationContext

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

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

于 2012-08-25T12:06:25.680 回答