本文介绍了请告诉我使用的风险TPL与ConcurrentDictionary与" addValueFactory"? MSDN意味着线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说,大约addValueFactory在多线程环境下

有这个一个封闭的连接问题,但似乎没有任何已经完成。当我读到上面摘录我猜,这些东西之一的也许的是发生了什么:

  1. 更​​新()方法被不断调用,直到它成功(可能变成缓慢/论点,即应在高负载下是可以避免的。)

  2. 该更新将被丢弃,并且应用程序认为它成功了。 (腐败)

  3. 的数据被更新的变量的线程本地副本,而不是其他的线程。 (这可能是一个延伸,但由于它不记录任何可能发生的)

谁能解释这是什么句话的意思?


第2

@Douglas共享code,我修改。有趣的是,看看有多少次,每次添加,被称为VS每次更新。输出是有趣的,因为只有一个返回值中有一个增加值。所有的人都更新,尽管添加被称为多次。

我想以某种方式prevent update方法被调用的。

  ConcurrentDictionary< INT,字符串>数=新ConcurrentDictionary< INT,字符串>();
        的Parallel.For(0,30中,x =>
        {
           变种返回= numbers.AddOrUpdate(1,
                I =>
                {
                    Console.WriteLine(addValueFactory被称为);
                    返回i.ToString()+AAA+ X;
                },
                (I,S)=>
                {
                    Console.WriteLine(updateValueFactory被称为);
                    返回i.ToString()+U+ X;
                });

           Console.WriteLine(返回);
        });
 

输出

  addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
updateValueFactory被称为
addValueFactory被称为
updateValueFactory被称为
addValueFactory被称为
1u15
updateValueFactory被称为
addValueFactory被称为
1u24
updateValueFactory被称为
1u25
updateValueFactory被称为
updateValueFactory被称为
1AAA0
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u26
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u18
updateValueFactory被称为
1u19
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u21
1u20
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u22
updateValueFactory被称为
1u16
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1U1
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u3
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1U4
1U2
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u6
1u27
updateValueFactory被称为
updateValueFactory被称为
1u23
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u9
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u10
updateValueFactory被称为
1u12
updateValueFactory被称为
updateValueFactory被称为
1u17
1u7
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u28
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u11
updateValueFactory被称为
updateValueFactory被称为
1u8
updateValueFactory被称为
updateValueFactory被称为
1u5
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
1u29
1u13
updateValueFactory被称为
1u14
 

解决方案

在实践中,这意味着唯一的事情是,你的 addValueFactory 方法应该是线程安全的的幂等的,这意味着它不会给不正确的结果,如果它被多次调用(可能同时)为相同的值。

考虑下面的人为的例子:

  ConcurrentDictionary< INT,字符串>数=新ConcurrentDictionary< INT,字符串>();
的Parallel.For(0,10中,x =>
{
    numbers.AddOrUpdate(1,
        I =>
        {
            Console.WriteLine(addValueFactory被称为);
            返回i.ToString();
        },
        (I,S)=>
        {
            Console.WriteLine(updateValueFactory被称为);
            返回i.ToString();
        });
});
 

如果在 AddOrUpdate 方法完全同步,那么你所期望的输出记录单个 addValueFactory 通话,随后九 updateValueFactory 通话。然而,由于所提到的条款,你可能会得到多个 addValueFactory 调用来代替。

  addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
addValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
updateValueFactory被称为
 

在大多数情况下,这是一种良性的竞争状态,特别是因为大多数 addValueFactory 代表们不需要改变任何状态。

MSDN says the following about addValueFactory in a multi threaded environment:

There is a closed connect issue on this, but nothing seems to have been done. When I read the above excerpt I guess that one of these things might be happening:

  1. The Update() method is called continuously until it succeeds (could turn into slowness/contention that should be avoided under high load.)

  2. The update is discarded, and the application thinks it succeeded. (corruption)

  3. The data is updated on the thread local copy of the variable, and not the other threads. (This might be a stretch, but since it's not documented anything might be happening)

Can anyone explain what that sentence means?


Part 2

@Douglas shared code which I modified. It is interesting to see how many times each "Add" was called vs each "update". The output is interesting because only one return value has an "add" value in it. All others are "updated" despite Add being called multiple times.

I want to somehow prevent the update method from being called at all.

        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);
        });

output

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
解决方案

In practice, the only thing it means is that your addValueFactory method should be thread-safe and idempotent, meaning that it won't give incorrect results if it is called multiple times (possibly concurrently) for the same value.

Consider the following contrived example:

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();
        });
});

If the AddOrUpdate method was perfectly synchronized, then you would expect the output to record a single addValueFactory call, followed by nine updateValueFactory calls. However, due to the mentioned clause, you may get multiple addValueFactory calls instead.

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

In the majority of cases, this is a benign race condition, particularly since most addValueFactory delegates would not need to alter any state.

这篇关于请告诉我使用的风险TPL与ConcurrentDictionary与&QUOT; addValueFactory&QUOT;? MSDN意味着线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:12