c# - 如何让 BackgroundWorker ProgressChanged 事件按顺序执行?

标签 c# .net backgroundworker race-condition

考虑以下代码:

private static BackgroundWorker bg = new BackgroundWorker();

static void Main(string[] args) {
  bg.DoWork += bg_DoWork;
  bg.ProgressChanged += bg_ProgressChanged;
  bg.WorkerReportsProgress = true;
  bg.RunWorkerAsync();

  Thread.Sleep(10000);
}

static void bg_ProgressChanged(object sender, ProgressChangedEventArgs e) {
  Console.WriteLine(e.ProgressPercentage);
  Thread.Sleep(100);
  Console.WriteLine(e.ProgressPercentage);
}

static void bg_DoWork(object sender, DoWorkEventArgs e) {
  for (int i = 0; i < 10; i++) {
    bg.ReportProgress(i);
  }
}

运行时得到以下输出:

0 1 1 2 0 3 2 3 5 4 4 6 5 7 7 8 6 9 8 9

我知道问题是 BackgroundWorker 为每次调用 ReportProgress 启动的线程之间的竞争条件。

如何确保每个 bg_ProgressChanged 的​​整个主体都按照我调用它们的顺序执行? 那就是我想得到

0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9

结果。

最佳答案

BackgroundWorker 在调用 RunWorkerAsync() 的线程的当前 SynchronizationContext 上引发 ProgressChanged 事件。

默认的 SynchronizationContext 在没有任何同步的情况下在 ThreadPool 上运行回调。

如果您在 UI 应用程序(WPF 或 WinForms)中使用 BackgroundWorker,它将使用该 UI 平台的 SynchronizationContext,它将按顺序执行回调。

关于c# - 如何让 BackgroundWorker ProgressChanged 事件按顺序执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8039587/

相关文章:

.net - 适用于 Windows 7 手机的 ORM 映射器

c# - 如何将 app.config 添加到 Visual Studio 2012 Web Express lib 项目?

c# - 如何加载多个mscorlib.dll并分别调用它们的内部函数?

java - 在基于 PHP 的应用程序中进行后台处理的最佳方式

vb.net - 进度条和后台 worker

c# - 林克?重构foreach

c# - 为什么我的进程只是打开一个空白窗口并立即关闭它?

c# - Objective C 中的 Xamarin Studio 类 HttpWebRequest 替代品是什么?

c# - 如何声明一个二维字符串数组?

c# - 在 C# 中检测 USB 设备的插入和移除