[英]C# How to get multiple tasks to start and then await them
我正在努力使我的任务运行。 我相信它们不会启动,等待永远不会返回,这样我的应用程序就不会再运行了。 它旨在处理多个数据集(在执行时即为已知),因此我使用循环将它们添加,它看起来是这样的:
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = new Task<ProcessedItem>(
() => ProcessItems(group.ToList(), group.Key));
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
它停在Task.WhenAll。 我认为它们根本没有启动,我在另一个方法中有一个类似的代码,但是在这里我将函数直接传递给任务:
Task<ReturnType>(Func);
我相信是造成差异的原因,由于参数的原因,我无法通过这种方式传递差异。 我应该如何修改我的代码使其起作用? 我应该明确启动每个任务吗? 如果任务在等待之前完成,这不会破坏await关键字吗?
我认为他们根本还没有开始
您肯定是正确的。 new Task()
返回一个“冷任务”,这是一个尚未开始使您明确调用Task.Start()
的任务。 文档清楚地说明了这一点 :
实例化Task对象并启动任务的最常见方法是调用静态
Task.Run(Action)
或TaskFactory.StartNew(Action)
方法,而不是调用此构造方法。 此构造函数提供的唯一优点是,它允许将对象实例化与任务调用分开。
这就是为什么您不应该使用Task
构造函数,而是使用工厂方法的原因之一,该方法为您提供了一个“热任务”,该任务已经启动 。 在这里, Task.Run
将是合适的:
var tasks = lp.Select(group => Task.Run(() => ProcessItems(group.ToList(), group.Key)));
await Task.WhenAll(tasks);
对于启动,您需要调用Start()
方法,并且使用此片段的方法必须分配有async
关键字
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = new Task<ProcessedItem>(() => ProcessItems(group.ToList(), group.Key));
t.Start();
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
它将等待内部的所有任务完成,然后tasks
将完成执行
或者您可以使用Task.Run()
方法代替Start()
Task.Run()
方法
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = Task.Run(() => ProcessItems(group.ToList(), group.Key));
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.