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

dia*_*ler 4 .net c# backgroundworker

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

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

Dou*_*las 6

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

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

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

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