C#如何启动多个任务然后等待它们

时间:2015-11-16 10:35:52

标签: c# asynchronous async-await task-parallel-library

我努力让我的任务得以运行。我相信他们不会开始,等待永远不会回来,这样我的应用程序永远不会进一步运行。它意味着处理多个数据集(在执行时已知),因此我使用循环添加它们,它看起来像这样:

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之前完成,那么是否会破坏await关键字?

2 个答案:

答案 0 :(得分:5)

  

我认为他们根本没有开始

你当然是正确的。 Label会返回一个&#34;冷任务&#34;,这是一项尚未开始让您明确调用new Task()的任务。 The docs spell this out clearly

  

而不是调用此构造函数,这是最常见的方法   实例化一个Task对象并通过调用static来启动任务   Task.Start()Task.Run(Action)方法。唯一的   这个构造函数提供的优点是它允许对象   实例化与任务调用分开。

这是您不应该使用TaskFactory.StartNew(Action)构造函数的原因之一,而是使用工厂方法,为您提供热门任务&#34;哪个已经启动。在这里,Task是合适的:

Task.Run

答案 1 :(得分:2)

要开始使用,您需要调用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内的所有任务完成其执行

时,它将等待

或者您可以使用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);

(...)