在C#/ .NET中是不可复制的"标志"线程安全吗?

abo*_*u00 5 .net c# asynchronous thread-safety

(注意:我已经问过这个问题,但答案是针对Java的,所以我问C#和.NET框架的问题.这不是重复的.)

我一直在使用这种模式,但我最近才开始认为这样做可能不太好.基本上,我使用这种模式的一些变体:

public class SampleAsync
{
    public SampleAsync() { }

    private bool completed;
    public void Start()
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, e) => {
            //... do something on a different thread
            completed = true;
        };
        worker.RunWorkerAsync();
    }

    public void Update()
    {
        if (!completed) return;
        //... do something else
    }
}
Run Code Online (Sandbox Code Playgroud)

*用户负责确保Start只调用一次.Update随时随地被召唤.

我一直认为这在C#/ .NET框架中是线程安全的,因为即使没有严格的同步,我也只能设置completed为true.一旦被观察到true,它将不会重置为false.它在构造函数中初始化为false,根据定义,它是线程安全的(除非你在其中做了一些愚蠢的事情).那么,以这种方式使用不可复制的标志是否安全?(如果是这样,它甚至可以提供任何性能优势吗?)

谢谢

Mar*_*der 3

您的代码是线程安全的,因为bool是原子类型。

微软软件定义网络:

以下数据类型的读取和写入是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。此外,对具有前面列表中的基础类型的枚举类型的读取和写入也是原子的。其他类型(包括 long、ulong、double 和decimal)以及用户定义类型的读取和写入不保证是原子的。除了为此目的而设计的库函数之外,不保证原子读取-修改-写入,例如在递增或递减的情况下。

请参阅:http ://msdn.microsoft.com/en-us/library/aa691278(v=vs.71).aspx

请用以下标记您的字段volatile

 private volatile bool completed;
Run Code Online (Sandbox Code Playgroud)

微软软件定义网络:

易失性关键字表示程序中的字段可以被操作系统、硬件或并发执行线程等修改。

请参阅:http ://msdn.microsoft.com/en-us/library/x13ttww7(v=vs.71).aspx