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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…