【发布时间】:2021-04-07 23:59:04
【问题描述】:
有人可以解释或指向一些可以向我解释为什么此代码不会引发任何异常的文档:
var d = new Dictionary<object, object>();
System.Threading.Tasks.Parallel.ForEach(new Action[] {
() => {
System.Threading.Tasks.Parallel.For(0, 1024, i => {
d.Add(new object(), new object());
});
},
() => {
System.Threading.Tasks.Parallel.For(0, 1024, i => {
d.TryGetValue(new object(), out _);
});
},
}, a => a());
我尝试在我的 8 核计算机上运行它,期望某些东西会引发有关无效操作或空引用等的异常,但它从来没有。虽然我最终得到了一个包含错误数量元素的字典,但它如何不会抛出异常和/或崩溃?
【问题讨论】:
-
根据文档
Add,如果密钥已经在字典中,则不会发生这种情况,因为您每次都创建一个新对象。而TryGetValue设计为不扔。那么您究竟会期待哪些例外情况? -
@juharr 预计两个线程同时发生重新平衡会造成一些破坏......但由于 OP 只进行 1000 次迭代,
Parallel.ForEach甚至不需要运行足够的线程来导致真正的麻烦很难可靠地触发。此外,总体上不正确的数据是不受保护的多线程访问更常见的结果,但 OP 根本不关心正确性。 -
定义上的竞争条件意味着它可能不会在大多数运行中引起问题。您是否运行过 1000 万次测试?
标签: c# thread-safety clr race-condition