Why doesn't BackgroundWorker require a call in the ProgressChanged event handler?

Since the ProgressChanged event handler is created from somewhere inside the DoWork event DoWork , shouldn't they be called in the asynchronous operation thread, which DoWork also works instead of the user interface thread, and therefore require Invoke or BeginInvoke to control the controls?

I guess some kind of magic happens in the ReportProgress method, but how does it even know which one is the right thread to call ProgressChanged event handlers on?

+4
source share
1 answer

When you call RunWorkerAsync , BackgroundWorker internally creates a new AsyncOperation associated with the current synchronization context, which is retrieved through the AsyncOperationManager.SynchronizationContext static property.

This synchronization context will be an instance of the class derived from the SynchronizationContext . The specific type depends on the provider of the synchronization model used by your application. If you use Windows Forms, it will be WindowsFormsSynchronizationContext ; by WPF; it will be a DispatcherSynchronizationContext .

When you then call ReportProgress in the background thread, BackgroundWorker will internally call Post for the aforementioned SynchronizationContext instance, thereby sending the operation to the linked thread asynchronously.

On Windows Forms, this is implemented as a call to Control.BeginInvoke ; at WPF, it becomes Dispatcher.BeginInvoke .

+6
source

All Articles