【发布时间】:2019-11-19 15:08:00
【问题描述】:
我目前正在处理一些线程敏感代码。
在我的代码中,我有一个由两个不同线程操作的对象列表。一个线程可以将对象添加到此列表中,而另一个线程可以将其设置为 null。
在上面的参考资料中,它特别提到了代表:
myDelegate?.Invoke()
相当于:
var handler = myDelegate;
if (handler != null)
{
handler(…);
}
我的问题是,List<> 的这种行为是否相同?例如:
是:
var myList = new List<object>();
myList?.Add(new object());
保证等价于:
var myList = new List<object>();
var tempList = myList;
if (tempList != null)
{
tempList.Add(new object());
}
?
编辑:
请注意,(委托的工作方式)之间存在差异:
var myList = new List<int>();
var tempList = myList;
if (tempList != null)
{
myList = null; // another thread sets myList to null here
tempList.Add(1); // doesn't crash
}
和
var myList = new List<int>();
if (myList != null)
{
myList = null; // another thread sets myList to null here
myList.Add(1); // crashes
}
【问题讨论】:
-
为什么不直接编写代码并测试您的假设是否正确?
-
我不知道如何检验我的假设,在 TheGeneral 的回答之前我不知道如何查看编译后的代码。
-
至于线程安全部分,您可能需要阅读this,因为您可能想了解与委托有关的竞争条件。
-
@Enigmativity:问题是“在这种情况下,编译器、抖动或 CPU 是否有可能引入额外的读取?”您不能编写任何代码来测试该命题!您只能编写代码来测试“这个特定的编译器、抖动和 CPU 在我运行代码的那天是否没有引入额外的读取?”这不是需要回答的问题。
-
@EricLippert - 谢谢你,埃里克。在座的所有人中,你是我喜欢,甚至期待被纠正的一个人。 :-)
标签: c# .net delegates null-conditional-operator