首页 > 解决方案 > 并行 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);
                        }


                    });

标签: c#multithreadingthread-safetylockingconcurrentdictionary

解决方案


Accessing the value by its indexer isnt thread safe. Use one of the other methods instead which insure thread safety like AddOrUpdate through Func. However which approach you choose will depend entirely on your needs

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

AddOrUpdate(TKey, Func, Func, TArg)

Uses the specified functions and argument to add a key/value pair to the ConcurrentDictionary if the key does not already exist, or to update a key/value pair in the ConcurrentDictionary if the key already exists.

It should be noted that, sometimes the ConcurrentDictionary may enter the lock, see that the value has changed since it read it, and try the delegate again. So it may have unexpected side effects in other certain situations


推荐阅读