BackgroundWorker.CancellationPending线程安全如何? [英] How is BackgroundWorker.CancellationPending thread-safe?

查看:180
本文介绍了BackgroundWorker.CancellationPending线程安全如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

取消BackgroundWorker的操作的方法是调用BackgroundWorker.CancelAsync():

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();
}

在BackgroundWorker.DoWork事件处理程序中,我们检查BackgroundWorker.CancellationPending:

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();
    }
}

上述想法遍布整个网络,包括在 MSDN页面上用于BackgroundWorker .

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?

我已经查看了ILSpy中的BackgroundWorker类-CancelAsync()只需将cancelPending设置为true而不使用内存屏障,而CancellationPending只需返回cancelPending而不使用内存屏障即可.

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.

根据此Jon Skeet页面,以上为不是线程安全.但是 BackgroundWorker.CancellationPending的文档说, 此属性是供工作线程使用的,工作线程应定期检查CancellationPending并在将其设置为true时中止后台操作."

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?

推荐答案

它是线程安全的.
代码

It is thread-safe.
The code

  while (!backgroundWorker.CancellationPending) 

正在读取属性,编译器知道它无法缓存结果.

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

并且由于在正常框架中,每个Write都与VolatileWrite相同,因此CancelAsync()方法仅可以设置一个字段.

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

这篇关于BackgroundWorker.CancellationPending线程安全如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆