C# 如何让多个任务开始然后等待它们
C# How to get multiple tasks to start and then await them
我正在努力完成我的任务 运行。我相信他们不会启动并且永远不会等待 returns,这样我的应用程序就不会再 运行 了。它旨在处理多个数据集(在执行时已知),因此我使用循环添加它们,它看起来是这样的:
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 关键字吗?
为了启动,您需要调用 Start()
method.And 您使用此片段的方法必须分配有 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);
(...)
I think they're not started at all
你肯定是对的。 new Task()
returns 一个 "cold task",这是一个尚未开始的任务,需要您在其上显式调用 Task.Start()
。 The docs spell this out clearly:
Rather than calling this constructor, the most common way to
instantiate a Task object and launch a task is by calling the static
Task.Run(Action)
or TaskFactory.StartNew(Action)
method. The only
advantage offered by this constructor is that it allows object
instantiation to be separated from task invocation.
这就是为什么你不应该使用 Task
构造函数,而是使用工厂方法的原因之一,它为你提供了 "hot task",也就是 [=24] =]已经开始。在这里,Task.Run
是合适的:
var tasks = lp.Select(group => Task.Run(() => ProcessItems(group.ToList(), group.Key)));
await Task.WhenAll(tasks);
我正在努力完成我的任务 运行。我相信他们不会启动并且永远不会等待 returns,这样我的应用程序就不会再 运行 了。它旨在处理多个数据集(在执行时已知),因此我使用循环添加它们,它看起来是这样的:
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 关键字吗?
为了启动,您需要调用 Start()
method.And 您使用此片段的方法必须分配有 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);
(...)
I think they're not started at all
你肯定是对的。 new Task()
returns 一个 "cold task",这是一个尚未开始的任务,需要您在其上显式调用 Task.Start()
。 The docs spell this out clearly:
Rather than calling this constructor, the most common way to instantiate a Task object and launch a task is by calling the static
Task.Run(Action)
orTaskFactory.StartNew(Action)
method. The only advantage offered by this constructor is that it allows object instantiation to be separated from task invocation.
这就是为什么你不应该使用 Task
构造函数,而是使用工厂方法的原因之一,它为你提供了 "hot task",也就是 [=24] =]已经开始。在这里,Task.Run
是合适的:
var tasks = lp.Select(group => Task.Run(() => ProcessItems(group.ToList(), group.Key)));
await Task.WhenAll(tasks);