我需要在控制台应用程序中运行多个异步任务,并在进一步处理之前等待它们全部完成。
有很多文章,但我似乎越读越困惑。我已经阅读并理解了Task库的基本原理,但我显然在某个地方遗漏了一个链接。
我知道可以将任务串联起来,这样它们就可以在另一个任务完成后开始(这几乎是我读过的所有文章的场景),但我希望所有任务同时运行,并且我想知道它们都完成后的情况。
对于这样的场景,最简单的实现是什么?
我需要在控制台应用程序中运行多个异步任务,并在进一步处理之前等待它们全部完成。
有很多文章,但我似乎越读越困惑。我已经阅读并理解了Task库的基本原理,但我显然在某个地方遗漏了一个链接。
我知道可以将任务串联起来,这样它们就可以在另一个任务完成后开始(这几乎是我读过的所有文章的场景),但我希望所有任务同时运行,并且我想知道它们都完成后的情况。
对于这样的场景,最简单的实现是什么?
当前回答
如果你正在使用async/await模式,你可以像这样并行运行几个任务:
public async Task DoSeveralThings()
{
// Start all the tasks
Task first = DoFirstThingAsync();
Task second = DoSecondThingAsync();
// Then wait for them to complete
var firstResult = await first;
var secondResult = await second;
}
其他回答
这是我如何使用数组Func<>:
var tasks = new Func<Task>[]
{
() => myAsyncWork1(),
() => myAsyncWork2(),
() => myAsyncWork3()
};
await Task.WhenAll(tasks.Select(task => task()).ToArray()); //Async
Task.WaitAll(tasks.Select(task => task()).ToArray()); //Or use WaitAll for Sync
还有另一个答案……但我通常会遇到这样的情况,当我需要同时加载数据并将其放入变量中,比如:
var cats = new List<Cat>();
var dog = new Dog();
var loadDataTasks = new Task[]
{
Task.Run(async () => cats = await LoadCatsAsync()),
Task.Run(async () => dog = await LoadDogAsync())
};
try
{
await Task.WhenAll(loadDataTasks);
}
catch (Exception ex)
{
// handle exception
}
你可以使用WhenAll,它将返回一个可等待的任务,或者WaitAll,它没有返回类型,将阻止进一步的代码执行,类似于线程。休眠,直到所有任务都完成、取消或出错。
WhenAll |
WaitAll |
|
---|---|---|
Any of the supplied tasks completes in a faulted state | A task with the faulted state will be returned. The exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks. | An AggregateException will be thrown. |
None of the supplied tasks faulted but at least one of them was canceled | The returned task will end in the TaskStatus.Canceled state |
An AggregateException will be thrown which contains an OperationCanceledException in its InnerExceptions collection |
An empty list was given | An ArgumentException will be thrown |
The returned task will immediately transition to a TaskStatus.RanToCompletion State before it's returned to the caller. |
Doesn't block the current thread | Blocks the current thread |
例子
var tasks = new Task[] {
TaskOperationOne(),
TaskOperationTwo()
};
Task.WaitAll(tasks);
// or
await Task.WhenAll(tasks);
如果你想以特定的顺序运行任务,你可以从这个答案中得到灵感。
你可以创建很多任务,比如:
List<Task> TaskList = new List<Task>();
foreach(...)
{
var LastTask = new Task(SomeFunction);
LastTask.Start();
TaskList.Add(LastTask);
}
Task.WaitAll(TaskList.ToArray());
如果你正在使用async/await模式,你可以像这样并行运行几个任务:
public async Task DoSeveralThings()
{
// Start all the tasks
Task first = DoFirstThingAsync();
Task second = DoSecondThingAsync();
// Then wait for them to complete
var firstResult = await first;
var secondResult = await second;
}