Reputation: 4835
Since the ProgressChanged
event handler is raised from somewhere within the DoWork
event handlers, shouldn't they be called on the asynchronous operation thread, which DoWork
also runs on, instead of the UI thread, and therefore require Invoke or BeginInvoke
to manipulate controls?
My guess is that some magic is happening within the ReportProgress
method, but how does it even know, which one is the correct thread to invoke the ProgressChanged
event handlers on?
Upvotes: 4
Views: 682
Reputation: 54877
When you call RunWorkerAsync
, the BackgroundWorker
internally creates a new AsyncOperation
associated with the current synchronization context, as retrieved through the AsyncOperationManager.SynchronizationContext
static property.
This synchronization context would be an instance of a class deriving from SynchronizationContext
. The specific type depends on the synchronization model provider your application uses. If you’re running Windows Forms, it would be WindowsFormsSynchronizationContext
; on WPF; it would be DispatcherSynchronizationContext
.
When you subsequently call ReportProgress
on the background thread, the BackgroundWorker
would internally call Post
on the aforementioned SynchronizationContext
instance, thereby dispatching the operation to the associated thread asynchronously.
In Windows Forms, this is implemented as a Control.BeginInvoke
call; on WPF, it becomes a Dispatcher.BeginInvoke
call.
Upvotes: 6