c# - 并行 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);
}
});
解决方案
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
推荐阅读
- python - 如何仅在单击按钮时将输入的字符串分配给变量?
- javascript - 防止 href 使用网站地址自动完成
- tabulator - 制表符 - 列格式不正确
- ios - Sinch iOS Callkit/Pushkit
- ruby-on-rails - 如何正确测试 Rails 中是否出现错误?
- json - 逻辑应用程序:在 WebApp 中显示文档并将其安全地保存到本地计算机
- c# - 桌面(不是 iOS)Unity Xcode 构建上的 AddBuildProperty?
- postgresql - 如何在插入新行后立即将自动生成的主键值保存到第二列
- java - 如何使用 gradle bnd (bndtools) 将“Embedded-Artifacts”部分添加到 Manifest?
- typescript - 如何检查数组是否在打字稿中包含空值?