关于多线程环境中的addValueFactory的MSDN says the following:



There is a closed connect issue on this,但是似乎什么也没做。当我阅读以上摘录时,我猜测可能正在发生以下情况之一:

  • 连续调用Update()方法,直到成功为止(可能会变成慢速/争用,应在高负载下避免。)
  • 更新被放弃,应用程序认为更新成功。 (腐败)
  • 数据在变量的线程本地副本上更新,而不在其他线程上更新。 (这可能是一小段时间,但是由于未记录在案,所以可能正在发生任何事情)

  • 谁能解释这句话的意思?

    第2部分

    @Douglas共享了我修改的代码。有趣的是看到每个“添加”相对于每个“更新”被调用了多少次。输出很有趣,因为只有一个返回值中包含“加”值。尽管“添加”被多次调用,但其他所有"file"都被“更新”。

    我想以某种方式阻止更新方法被调用。
            ConcurrentDictionary<int, string> numbers = new ConcurrentDictionary<int, string>();
            Parallel.For(0, 30, x =>
            {
               var returned = numbers.AddOrUpdate(1,
                    i =>
                    {
                        Console.WriteLine("addValueFactory has been called");
                        return i.ToString() + "AAA" + x;
                    },
                    (i, s) =>
                    {
                        Console.WriteLine("updateValueFactory has been called");
                        return i.ToString() + "u" + x;
                    });
    
               Console.WriteLine(returned);
            });
    

    输出
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    updateValueFactory has been called
    addValueFactory has been called
    updateValueFactory has been called
    addValueFactory has been called
    1u15
    updateValueFactory has been called
    addValueFactory has been called
    1u24
    updateValueFactory has been called
    1u25
    updateValueFactory has been called
    updateValueFactory has been called
    1AAA0
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u26
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u18
    updateValueFactory has been called
    1u19
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u21
    1u20
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u22
    updateValueFactory has been called
    1u16
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u1
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u3
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u4
    1u2
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u6
    1u27
    updateValueFactory has been called
    updateValueFactory has been called
    1u23
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u9
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u10
    updateValueFactory has been called
    1u12
    updateValueFactory has been called
    updateValueFactory has been called
    1u17
    1u7
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u28
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u11
    updateValueFactory has been called
    updateValueFactory has been called
    1u8
    updateValueFactory has been called
    updateValueFactory has been called
    1u5
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    1u29
    1u13
    updateValueFactory has been called
    1u14
    

    最佳答案

    实际上,这意味着您的addValueFactory方法应该是线程安全的和幂等的,这意味着如果对同一值多次(可能同时)调用它,它不会给出错误的结果。

    考虑以下人为的示例:

    ConcurrentDictionary<int, string> numbers = new ConcurrentDictionary<int, string>();
    Parallel.For(0, 10, x =>
    {
        numbers.AddOrUpdate(1,
            i =>
            {
                Console.WriteLine("addValueFactory has been called");
                return i.ToString();
            },
            (i, s) =>
            {
                Console.WriteLine("updateValueFactory has been called");
                return i.ToString();
            });
    });
    

    如果AddOrUpdate方法完全同步,则您希望输出记录一个addValueFactory调用,然后是九个updateValueFactory调用。但是,由于提到了该子句,您可能会得到多个addValueFactory调用。
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    addValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    updateValueFactory has been called
    

    在大多数情况下,这是一个良性竞争条件,尤其是因为大多数addValueFactory委托(delegate)人都不需要更改任何状态。

    09-30 21:21