并行并发字典计数器

时间:2019-01-15 00:57:52

标签: c# multithreading thread-safety locking concurrentdictionary

该程序类似于单词计数。

我有一个大文件,每行包含一个键和2个数字

我需要对每个键的增量值求和。

给出了所有键,文本文件将没有列表中没有的任何键。

问题是每当我使用相同的输入运行时,我得到的总和就会不同。

public static ConcurrentDictionary<string, ulong> entries = new ConcurrentDictionary<string, ulong>();
//sequentially load keys into entries 

               ParallelOptions op = new ParallelOptions();
                op.MaxDegreeOfParallelism = nThread;
                Parallel.ForEach(lines, op, (one) =>
                    {
                        string[] parts = one.Split('\t');

                        string key = parts[1];

                        //get length
                        ulong len = Convert.ToUInt64(parts[4]) - Convert.ToUInt64(parts[3]);


                        if (entries.ContainsKey(key))
                        {
                                entries[key] += len;

                        }
                        else
                        {
                            Console.WriteLine("key not found: " + key);
                        }


                    });

1 个答案:

答案 0 :(得分:1)

通过其索引器访问值不是线程安全的。使用其他方法之一来确保线程安全,例如AddOrUpdateFunc。但是,您选择哪种方法将完全取决于您的需求

entries.AddOrUpdate(key, len, (s, value) => value + len);

AddOrUpdate(TKey, Func, Func, TArg)

  

使用指定的函数和参数将键/值对添加到   如果密钥还没有,则为ConcurrentDictionary   存在,或更新其中的键/值对   如果密钥已经存在,则为ConcurrentDictionary。

应注意,有时ConcurrentDictionary可能会进入锁,看到自读取值以来该值已更改,然后再次尝试委托。因此它在其他某些情况下可能会产生意想不到的副作用