具有属性分配的线程安全构造 [英] thread safe construction with attribute assignment

查看:84
本文介绍了具有属性分配的线程安全构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自

class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }
}

Cat cat = new Cat { Age = 10, Name = "Fluffy" };

对象初始化器语法允许您创建实例,并且 之后,它将具有其分配的属性的新创建的对象分配给分配中的变量.

The object initializers syntax allows you to create an instance, and after that it assigns the newly created object, with its assigned properties, to the variable in the assignment.

vs https://stackoverflow.com/a/19138412/432976

var albumData = new Album 
{
     Name = "Albumius",
     Artist = "Artistus",
     Year = 2013
 };

是此等效代码的语法简写:

is syntactic shorthand for this equivalent code:

var albumData = new Album();
albumData.Name = "Albumius";
albumData.Artist = "Artistus";
albumData.Year = 2013;

编译后两者是相同的.

问题: 这种构造+分配线程安全吗? (即,另一个读取cat的线程可以在创建Cat以及分配Age和Name的时间之间看到Cat吗?)

Question: is this stype of construction + assignment thread safe? (ie, could another thread reading cat see the Cat between when it was created, and when Age and Name are assigned)?

第一个似乎是这样,就像分配属性后一样,变量被分配了(线程安全顺序),第二个似乎是在编译的代码级别,顺序是不同的.

The first seems to say it is, as it is after the properties are assigned, the variable gets assigned (the threadsafe order), the second says that at a compiled code level, the order is different.

如果第二个是正确的,那么下面的代码是否足以避免另一个线程的竞争状态看到一半被构造的猫?

if the second is true, is the following code sufficient to avoid the race condition of another thread seeing a half constructed cat?

var myNewCat = new Cat { Age = 10, Name = "Fluffy" };
sharedCat = myNewCat;

我意识到这里存在着关于其他线程是否看到oldCat或newCat的二级竞争条件,但是在这种情况下,我唯一关心的是其他线程必须看到完整的Cat,而不是一半构造的Cat.

I realise that there are secondary race conditions here concerning if other threads see the oldCat or the newCat, but in this situation my only concern is that other threads must see a complete Cat, not a half constructed one.

推荐答案

使用以下示例类

public class Cat
{
    public int Age { get; set; }
    public string Name { get; set; }
}

C#2.0样式

代码

var cat1 = new Cat();
cat1.Age = 10;
cat1.Name = "Fluffy";

生成以下 IL 代码(使用

这基本上会创建变量实例及其可用的变量(来自

This basically creates the variable instance and its available (from stloc.0), so at that point it is available for another thread to pick it up in that state if it was exposed.

回答否,此版本不是线程安全的

Answer is no this version is not thread safe

C#3.0样式

自C#3起,我们可以执行称为代码

var cat1 = new Cat { Age = 10, Name = "Fluffy" };

生成以下IL代码

L_000c: newobj instance void ConsoleApp1.Cat::.ctor()
L_0011: dup 
L_0012: ldc.i4.s 10
L_0014: callvirt instance void ConsoleApp1.Cat::set_Age(int32)
L_0019: nop 
L_001a: dup 
L_001b: ldstr "Fluffy"
L_0020: callvirt instance void ConsoleApp1.Cat::set_Name(string)
L_0025: nop 
L_0026: stloc.0 

此处的主要区别是,由于类实例使用

The main difference here is the instance of the class is never pulled off the evaluation stack as it uses dup until its all done then does stloc.0 last.

该方法是否是线程安全的

这篇关于具有属性分配的线程安全构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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