How to make BackgroundWorker ProgressChanged events execute in sequence?

依然范特西╮ 提交于 2020-11-28 04:56:52

问题


Consider the following code:

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);
  }
}

When run I get the following output:

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

I understand that the issue is a race condition between the threads that BackgroundWorker starts for each call to ReportProgress.

How can I make sure that the whole body of each bg_ProgressChanged gets executed in the order I have called them? That is I would like to get

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

as a result.


回答1:


BackgroundWorker raises ProgressChanged events on the current SynchronizationContext of the thread that called RunWorkerAsync().

The default SynchronizationContext runs callbacks on the ThreadPool without any synchronization.

If you use BackgroundWorker in a UI application (WPF or WinForms), it will use that UI platform's SynchronizationContext, which will execute callbacks in order.




回答2:


Do not use this solution!!! May lead to deadlocks as SLaks has pointed it out.

I seem to have stumbled upon an answer. I changed the code the following way:

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

and now I get the output I want:

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



来源:https://stackoverflow.com/questions/8039587/how-to-make-backgroundworker-progresschanged-events-execute-in-sequence

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!