If I use a BackgroundWorker to modify data structures in my application, is there a guarantee that changes made on the background thread will be visible to the main (UI) thread when the BackgroundWorker completes (e.g. within the RunWorkerCompleted event handler)? For bonus points: if so, what is the mechanism that guarantees this?

2

There are 2 best solutions below

0
On BEST ANSWER

No, there is no such guarantee. You'll need to synchronize access to any shared memory yourself if you want to access it from multiple threads.

Of course if you use the BGW built in mechanisms for passing data between threads, such as through the Result or Progress data that it stores, then it will properly synchronize access to that data.

0
On

Yes, this is not something you have to worry about as long as you follow the BackgroundWorker contract. In other words, use the provided events to channel data to the UI thread, ProgressChanged and RunWorkerCompleted. The .NET Framework source code doesn't score any elegance points for this, the synchronization is not explicit. This is pretty common, it relies on implicit synchronization in many places.

But there are two that ensure the UI thread can see the updates. First is PostMessage(), a winapi function that's used to signal the UI thread that it needs to take a look at the invoke queue. Used here, you however can't see the lock at all, it is buried inside of Windows. The more easily recognizable one that you can see is inside the Winforms code that empties the invoke queue. It takes a lock before it starts iterating that queue. You can see it here, it is the lock on the threadCallbackList member.