【发布时间】:2019-02-28 13:44:04
【问题描述】:
我正在尝试将所有任务并行添加到列表中,然后等待它们。代码:
List<Task<bool>> tasks = new List<Task<bool>>();
Parallel.For(0, 500, file =>
{
tasks.Add(SomeTask());
});
Console.WriteLine("Total tasks = " + tasks.Count);
当我执行以下代码时,有时我会得到任务列表(tasks.Count)的大小为 493 或 500 或 498。但这不是确定性的。我该怎么办?
【问题讨论】:
-
您应该停止在这些任务中使用共享的非线程安全列表。
List<T>不是线程安全的。要么在你的代码周围添加一个锁来操作共享列表,使用适当的同步集合,或者做一些完全不同的不需要列表的事情(问题中的信息太少,最后一个选项太模糊,无法给出更多提示为)。 -
基本上,for-loop 并没有很快退出,但是列表添加没有同步,因此一些更新丢失了。很可能,如果您要查看其中的任务,您还会发现其他奇怪的东西,例如重复条目或空引用。
-
List<T>(在您的情况下为List<Task<bool>>)不是线程安全的;在Parallel.For内执行Add是危险的,很可能会导致不可预知的行为 -
尝试 PLinq (Parallel Linq) 而不是
Parallel.For:List<Task<bool>> tasks = Enumerable.Range(0, 500).AsParallel().Select(file => SomeTask()).ToList(); -
除了关于 List 和线程安全的 cmets 之外,使用 parallel.For() 将 500 个项目添加到 List 中绝对没有任何好处。
标签: c# multithreading task parallel.for