【发布时间】:2020-12-25 11:35:36
【问题描述】:
使用 ConcurrentDictionary 和 ConcurrentBag 来添加或更新值是否正确?
基本上尝试如下,
-
拥有包含数百万条记录的文件并尝试处理并提取到对象。
-
而 entry 就像,Key-Value 对,Key=WBAN 和 Value 作为对象。
var cd = new ConcurrentDictionary<String, ConcurrentBag<Data>>(); int count = 0; foreach (var line in File.ReadLines(path).AsParallel().WithDegreeOfParallelism(5)) { var sInfo = line.Split(new char[] { ',' }); cd.AddOrUpdate(sInfo[0], new ConcurrentBag<Data>(){ new Data() { WBAN = sInfo[0], Date = string.IsNullOrEmpty(sInfo[1]) ? "" : sInfo[1], time = string.IsNullOrEmpty(sInfo[2]) ? "" : sInfo[2] } } , (oldKey, oldValue) => { oldValue.Add(new Data() { WBAN = sInfo[0], Date = string.IsNullOrEmpty(sInfo[1]) ? "" : sInfo[1], time = string.IsNullOrEmpty(sInfo[2]) ? "" : sInfo[2] }); return oldValue; } ); }
【问题讨论】:
-
File.ReadLines(path).AsParallel().WithDegreeOfParallelism(5)- 这意味着什么?编写此并行代码毫无意义,因为您的程序是 IO 绑定的。你甚至没有使用 async-IO。你给自己制造了不必要的麻烦。 -
没有必要并行运行,除了让你头疼之外,它几乎什么都做不了,即使你让它工作也可能运行得更慢
-
您的代码还不必要地创建了一个新的
ConcurrentBag实例,因为ConcurrentDictionary会运行所有工厂回调,即使会发生冲突(默认情况下它会这样做,尽管有一些解决方法)。 -
实际上,文本文件有 2000 万条或更多记录。那么,它对并行处理有用吗?
-
如果你花更多的时间在CPU上处理,你可能会遇到一个案例,但瓶颈会是IO,这种情况下CPU上什么也没做(相对地)。此外,由于您正在阅读行尾,并且它可能已编码,因此没有简单的方法可以并行处理(但并非不可能)。最后,我会三思而后行将 200 万条记录拉入内存,这是大型对象堆上的大量不可移动数据。听起来你想要一个数据库
标签: c# multithreading parallel.foreach concurrentdictionary