Ehs*_*jad 0 c# parallel-processing parallel.foreach
我有一个方法,它读取一个文本文件,每行包含一个int值,为了使读取速度更快,我使用Parallel.ForEach,但我所看到的行为是意外的,我在文件中有800行但是当我运行这个方法时,每个时间它返回不同的HashSet计数,我在搜索后读取的是Parallel.ForEach生成多个线程并且当所有线程完成其工作时返回结果,但是我的代码执行矛盾,或者我在这里遗漏了一些重要的东西?
这是我的方法:
private HashSet<int> GetKeyItemsProcessed()
{
HashSet<int> keyItems = new HashSet<int>();
if (!File.Exists(TrackingFilePath))
return keyItems;
// normal foreach works fine
//foreach(var keyItem in File.ReadAllLines(TrackingFilePath))
//{
// keyItems.Add(int.Parse(keyItem));
//}
// this does not return right number of hashset rows
Parallel.ForEach(File.ReadAllLines(TrackingFilePath).AsParallel(), keyItem =>
{
keyItems.Add(int.Parse(keyItem));
});
return keyItems;
}
Run Code Online (Sandbox Code Playgroud)
HashSet.Add 不是线程安全的.
来自MSDN:
此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的.任何实例成员都不保证是线程安全的.
多线程时序的不可预测性可能并且似乎正在引发问题.
您可以将访问包装在同步构造中,这有时比并发集合更快,但在某些情况下可能无法加快速度.正如其他人所说,另一种选择是使用一个线程安全的集合像ConcurrenDictionary或者ConcurrentQueue,尽管这些可能有额外的内存开销.
请务必根据时间对任何结果进行基准测试.单线程访问的原始功能有时比处理线程开销更快.完全破坏这段代码可能不值得.
但最后一句话是,HashSet单独的,没有同步,对多线程操作来说简直是不可接受的.
| 归档时间: |
|
| 查看次数: |
610 次 |
| 最近记录: |