由于 ProgressChanged
事件处理程序是从 DoWork
事件处理程序中的某处引发的,它们不应该在异步操作线程上调用,DoWork
也运行在而不是 UI 线程上,因此需要 Invoke 或 BeginInvoke
来操作控件?
我的猜测是 ReportProgress
方法中发生了一些神奇的事情,但它怎么知道哪个是调用 ProgressChanged
事件处理程序的正确线程?
最佳答案
当您调用 RunWorkerAsync
时,BackgroundWorker
会在内部创建一个新的 AsyncOperation
与当前同步上下文关联,通过 AsyncOperationManager.SynchronizationContext
检索静态属性。
此同步上下文将是派生自 SynchronizationContext
的类的一个实例.具体类型取决于您的应用程序使用的同步模型提供程序。如果您运行的是 Windows 窗体,它将是 WindowsFormsSynchronizationContext
;在 WPF 上;它将是 DispatcherSynchronizationContext
.
当您随后在后台线程上调用 ReportProgress
时,BackgroundWorker
将在内部调用 Post
在上述 SynchronizationContext
实例上,从而将操作异步分派(dispatch)给关联的线程。
在 Windows 窗体中,这是作为 Control.BeginInvoke
实现的称呼;在 WPF 上,它变成了 Dispatcher.BeginInvoke
打电话。
关于c# - 为什么 BackgroundWorker 不需要在 ProgressChanged 事件处理程序中调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12121708/