Why doesn't a BackgroundWorker need Invoke in the ProgressChanged event handler?
.net, backgroundworker, c#
Solution
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.
Problem
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?