我正在尝试将所有任务并行添加到列表中,然后等待它们。代码:
DataTable dt_LearnDelivery = new DataTable();
当我执行以下代码时,有时我得到的任务列表(tasks.Count)的大小为493或500或498。但这不是确定性的。我该怎么办?
答案 0 :(得分:1)
您拥有所谓的race condition。您正在从多个线程访问列表而不进行同步,这会使列表处于怪异状态。
您可以改用像ConcurrentStack这样的线程安全对象(或ConcurrentBag或ConcurrentQueue,具体取决于您对集合的处理方式):
ConcurrentStack<Task<bool>> tasks = new ConcurrentStack<Task<bool>>();
Parallel.For(0, 500, file =>
{
tasks.Push(SomeTask());
});
Console.WriteLine("Total tasks = " + tasks.Count);
答案 1 :(得分:1)
返回任务的方法(例如SomeTask
)通常返回速度非常快,而并行调用它们的方法通常会导致执行速度较慢。
使用(非并行)LINQ构建任务集合更为正常:
var tasks = Enumerable.Range(0, 500).Select(file => SomeTask()).ToList();
Console.WriteLine("Total tasks = " + tasks.Count);
如果您的任务返回方法具有一些受CPU约束的代码,并且您确实需要在线程池线程上运行SomeTask
,则可以使用并行性。一种简单的方法是将呼叫包装在Task.Run
中:
var tasks = Enumerable.Range(0, 500).Select(file => Task.Run(() => SomeTask())).ToList();
Console.WriteLine("Total tasks = " + tasks.Count);