为什么并行访问和改变 System.Collections.Generic.Dictionary 不会导致异常/崩溃?

问题描述

有人可以解释或指向一些可以向我解释为什么此代码不会引发任何异常的文档:

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,i => {
            d.TryGetValue(new object(),out _);
        });
    },},a => a());

我尝试在我的 8 核计算机上运行它,期望某些事情会引发有关无效操作或空引用等的异常,但它从未如此。虽然我最终得到了一个元素数量错误的字典,但它如何不抛出异常和/或崩溃?

解决方法

仅仅因为某些东西不是线程安全的并不意味着从多个线程使用它会导致它抛出异常。 Dictionary 类不是线程安全的,一次只能由一个线程使用。它可能不包括对哪些线程同时访问它的任何检查,因为这太昂贵了。它只是假设一次只有一个线程访问它。

,

从多个线程并发变异一个非线程安全的组件可以保证既不发生异常也不崩溃。实际上,它绝对没有任何保证。组件的行为正式变为“未定义”,这意味着任何事情都可能发生,包括根本没有发生任何不好的事情。但是如果不愉快的事情发生了,那么你就不能去供应商那里填写错误报告,要求修复错误。因为没有bug。供应商可以通过以下方式回复您的请求:

尊敬的客户,封条破损,保修无效。你选择进入未知领域的大黑森林,在那里没有规则适用,现在你是一个人。