C#结构是否安全?

Kav*_*ian 8 c# parallel-processing concurrency struct thread-safety

C#struct是否是线程安全的?

例如,如果有:

struct Data
{
    int _number;
    public int Number { get { return _number; } set { _number = value; } }

    public Data(int number) { _number = number; }
}
Run Code Online (Sandbox Code Playgroud)

在另一种类型:

class DadData
{
    public Data TheData { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

是属性名为TheData,线程安全吗?

Mar*_*ell 9

好 - 最好的做法是结构应该总是(除了在一些非常具体的情况下,即使那时有风险)也是不可改变的.不可变数据始终是线程安全的.所以如果你遵循最佳实践并做到了这一点:

struct Data
{
    readonly int _number;
    public int Number { get { return _number; } }

    public Data(int number) { _number = number; }
}
Run Code Online (Sandbox Code Playgroud)

好的; 这是线程安全的.在所有其他情况下,答案是"可能不是".

还要注意原子性规则适用,因此DadData.TheData即使使用不可变结构,也不能假定单个读取或更新是线程安全的.你可以(特别是对于超大结构)有一个线程读取结构,而另一个线程重写它; 没有同步会发生坏事(最终).


cas*_*One 8

不,.NET中的结构本质上不是线程安全的.

然而,结构的复制语义与这种对话有很大关系.

如果您传递结构并以某种方式将它们分配给变量或按值传递参数(没有引用或输出关键字),则使用副本.

当然,这意味着对副本所做的任何更改都不会反映在原始结构中,但是在传递它们时需要注意的事项.

如果您以不涉及按值复制语义的方式直接访问结构(例如,访问静态字段,这是结构的类型,并且正如Marc Gravel在其答案中指出的那样,还有许多其他方式)跨多个线程,然后你必须考虑实例的线程安全性.