【发布时间】:2017-05-12 04:29:55
【问题描述】:
这并不像我想象的那么简单,需要启动许多任务来对一个对象进行操作。每个任务一个唯一的对象。第二部分是ContinueWith,当每个任务报告结果时。但是,我没有得到 WhenAll 类型的行为。希望有人能纠正我。
_tasks = new Task<AnalysisResultArgs>[_beansList.Count];
for (int loopCnt = 0; loopCnt < _beansList.Count; loopCnt++)
{
_tasks[loopCnt] = Task<AnalysisResultArgs>.Factory.StartNew(() =>
{
return _beansList[loopCnt].Analyze(newBeanData);
});
await _tasks[loopCnt].ContinueWith(ReportResults,
TaskContinuationOptions.RunContinuationsAsynchronously)
// do some housekeeping when all tasks are complete
}
private void ReportResults(Task<AnalysisResultArgs> task)
{
/* Do some serial operations
}
据我了解,_beansList.Count 任务将被启动,并且通过在 ContinueWith 上使用 await,在所有任务完成之前不会执行内务处理工作。我无法阻止,因为我需要确保能够限制传入数据以防止等待执行的任务过多。
我在哪里搞砸了,等待实际上完成了,即使不是所有的任务都已经完成,但仍会运行内务管理。
【问题讨论】:
-
请简化为完整并重现问题的最小示例。旁注:如果你使用
Task.Run代替StartNew,使用await代替ContinueWith,那么你的代码会更干净,表现更好。 -
Stephen,我感谢您的评论和您在这个主题上的公认权威,但是,这是一个最小的工作示例,减去了一些额外的类。您对 Task.Run 而不是 StartNew 和使用 await(我做过)而不是 ContinueWith 的声明,我会看看我是否可以在网上寻找为什么这样更好。我认为 ContinueWith 就是这个意思,而 await 就是它所说的意思。套用开始一个新任务并在任务完成时继续第二步。等到一切都结束。
-
这个例子并不完整。我无法将其粘贴到新项目中并在调试器中观察其行为。我在 why
StarNewis dangerous 和 whyContinueWithis dangerous 上有博文。 -
@StephenCleary 这些博客我有好几次了,它们帮了大忙。不,您不能将其粘贴到项目中并逐步执行。我为此道歉。您的 cmets 和其他 cmets 仍然有很大帮助。
标签: c# async-await task-parallel-library