Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

The way to cancel a BackgroundWorker's operation is to call BackgroundWorker.CancelAsync():

// RUNNING IN UI THREAD
private void cancelButton_Click(object sender, EventArgs e)
{
    backgroundWorker.CancelAsync();
}

In a BackgroundWorker.DoWork event handler, we check BackgroundWorker.CancellationPending:

// RUNNING IN WORKER THREAD
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    while (!backgroundWorker.CancellationPending) {
        DoSomething();
    }
}

The above idea is all over the web, including on the MSDN page for BackgroundWorker.

Now, my question is this: How on earth is this thread-safe?

I've looked at the BackgroundWorker class in ILSpy — CancelAsync() simply sets cancellationPending to true without using a memory barrier, and CancellationPending simply returns cancellationPending without using a memory barrier.

According to this Jon Skeet page, the above is not thread-safe. But the documentation for BackgroundWorker.CancellationPending says, "This property is meant for use by the worker thread, which should periodically check CancellationPending and abort the background operation when it is set to true."

What's going on here? Is it thread-safe or not?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
351 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...