How is BackgroundWorker.CancellationPending thread-safe? How is BackgroundWorker.CancellationPending thread-safe? multithreading multithreading

How is BackgroundWorker.CancellationPending thread-safe?


It is because BackgroundWorker inherits from Component which inherits from MarshalByRefObject. An MBRO object may reside on another machine or in another process or appdomain. That works by having the object impersonated by a proxy that has all of the exact same properties and methods but whose implementations marshal the call across the wire.

One side effect of that is that the jitter cannot inline methods and properties, that would break the proxy. Which also prevents any optimizations from being made that stores the field value in a cpu register. Just like volatile does.


It is thread-safe.
The code

  while (!backgroundWorker.CancellationPending) 

is reading a property and the compiler knows it can't cache the result.

And since in the normal framework every Write is the same as VolatileWrite, the CancelAsync() method can just set a field.


A good point and a very fair doubt. It sounds like not thread safe. I think MSDN also has the same doubt and that's why this is there under BackgroundWorker.CancelAsync Method.

Caution

Be aware that your code in the DoWork event handler may finish its work as a cancellation request is being made, and your polling loop may miss CancellationPending being set to true. In this case, the Cancelled flag of System.ComponentModel.RunWorkerCompletedEventArgs in your RunWorkerCompleted event handler will not be set to true, even though a cancellation request was made. This situation is called a race condition and is a common concern in multithreaded programming. For more information about multithreading design issues, see Managed Threading Best Practices.

I am not sure about BackgroundWorker class implementation. Looking at how it is using BackgroundWorker.WorkerSupportsCancellation property internally is important in this case.