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

标签 c# .net backgroundworker

由于 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/

相关文章:

c# - 接受多个参数的 BackgroundWorker 的替代方案?

c# - 列出文件夹中的所有文件 - 文件的完整路径

c# - IEnumerable<IEnumerable<int>> - 没有重复的 IEnumerable<int>

c# - 在 C# 应用程序中使用 LINQ to SQL 的最佳实践方法是什么? [设计模式]

c# - 从 .NET 探查器访问 ThreadStatic 字段

c# - 多线程或其他不同的东西

c# - 使用 Odbc C# .Net 连接到 Pick 数据库

C#:如何将参数键/值传递给函数?

c# - 在 C# 中使用 vb.net 类

c# - 当 doWork 调用时,BackgroundWorker 使应用程序崩溃