Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的静态列表分配是原子的_C# - Fatal编程技术网

C#中的静态列表分配是原子的

C#中的静态列表分配是原子的,c#,C#,根据该引用,保证在所有.NET平台上分配都是原子的。这个代码是原子的吗 public static List<MyType> _items; public static List<MyType> Items { get { if (_items== null) { _items= JsonConvert.DeserializeObject<List<MyType>>(Conf

根据该引用,保证在所有.NET平台上分配都是原子的。这个代码是原子的吗

public static List<MyType> _items;

public static List<MyType> Items
{
    get
    {
        if (_items== null)
        {
            _items= JsonConvert.DeserializeObject<List<MyType>>(ConfigurationManager.AppSettings["Items"]);
        }
        return _items;
    }
}
公共静态列表\u项;
公共静态列表项
{
得到
{
如果(_items==null)
{
_items=JsonConvert.DeserializeObject(ConfigurationManager.AppSettings[“items”]);
}
退货(物品);;
}
}

我知道可能会有多个对象。但是it项是否是原子的(我的意思是它将是null或List而不是中间的)?

不,此代码不是原子的-如果从多个线程并行访问
项,则
\u项实际上可能会被创建多次,并且不同的调用者可能会收到不同的值

此代码需要锁定,因为它首先执行读取、分支和写入(在昂贵的反序列化调用之后)。读和写本身是原子的,但是没有锁,没有什么可以阻止系统在读和写之间切换到另一个线程

在伪(ish)代码中,可能会发生以下情况:

if (_items==null)
    // Thread may be interrupted here.
{
    // Thread may be interrupted inside this call in many places,
    // so another thread may enter the body of the if() and
    // call this same function again.
    var s = ConfigurationManager.AppSettings.get_Item("Items");

    // Thread may be interrupted inside this call in many places,
    // so another thread may enter the body of the if() and
    // call this same function again.
    var i = JsonConvert.DeserializeObject(s);

    // Thread may be interrupted here.
    _items = i;
}

// Thread may be interrupted here.
return (_items);
这表明,在不锁定的情况下,多个调用者可以获得
列表的不同实例

您应该研究如何使用它,这将使这种初始化更加简单和安全

另外,请记住,
List
本身不是线程安全的-您可能需要使用不同的类型(如
ConcurrentDictionary
ReadOnlyCollection
),或者您可能需要对该列表的所有操作使用锁定


Rob在评论中指出,问题可能在于给定的赋值是否是原子的——引用的单个赋值(即单写)保证是原子的,但这并不能保证代码的安全性,因为这里不止一个赋值。

这是正确的,但我相信OP是在问这个任务是否是原子的。也就是说,永远不会有一个“半构造”的对象分配给
\u items
@Rob你可能是对的-让我更新答案来解释这一点。非常感谢。