我有一堆任务定义为:
Task t1 = new Task( () => { /* Do Something */ } );
Task t2 = new Task( () => { /* Do Something */ } );
Task t3 = new Task( () => { /* Do Something */ } );
Task t4 = new Task( () => { /* Do Something */ } );
List<Task> allTasks = new List<Task>();
allTasks.Add(t1);
allTasks.Add(t2); etc.
最后:
Task.WhenAll(allTasks).ContinueWith((t) =>
{
MyBlockingCollection.CompleteAdding();
});
foreach (Task t in allTasks)
{
t.Start();
}
我对上述代码的疑问:
这是使用任务的正确方法吗?
Task.WhenAll()
是自己启动任务还是我们必须明确启动它们。如果是这样,我们首先开始然后做Task.WhenALL()
?
我也需要对这些任务进行异常处理,你能否建议在任务中处理异常的正确方法。理想情况下,我希望任务在发生异常时将一些诊断信息写入文本文档。 / p>
我对任务世界有点新意,感谢您的帮助!
答案 0 :(得分:2)
Task.WhenAll()是自己启动任务还是我们必须启动任务 明确地启动它们。如果是这样,我们首先开始然后做 Task.WhenAll()?
在等待之后,您需要先单独启动每个任务。
我还需要对这些任务进行异常处理,..
每个任务都是独立的执行单元,因此异常处理在其范围内发生。这意味着您可以做的是将任务中的异常作为结果返回。主线程将读取结果并表现得恰当。
答案 1 :(得分:1)
如果您只是调用构造函数,那么这些Task
实例将无法运行。由于任务尚未启动,WhenAll
将永远不会返回,您将死锁。
改为使用System.Threading.Task.Run
。
Task t1 = Task.Run(() => { /* Do Something */ });
Task t2 = Task.Run(() => { /* Do Something */ });
...
删除启动任务的循环。
Task.Run方法(操作).NET Framework 4.5
将指定的工作排队以在ThreadPool上运行并返回任务 处理这项工作。
进一步阅读:Task Parallelism (Task Parallel Library)
关于异常处理,您可以使用Task
参数从延迟中访问所有结果,甚至例外:
Task.WhenAll(allTasks).ContinueWith((t) =>
{
if(t.RanToCompletion)
{
MyBlockingCollection.CompleteAdding();
}
else
{
Console.WriteLine(t.Exception);
}
});
有关此内容的更多信息:Exception Handling (Task Parallel Library)