如何从 WhenAll(任务数组)中获取结果



我有以下代码。

var tasks = new[]
{
Task.Factory.StartNew(() => GetSomething1()),
Task.Factory.StartNew(() => GetSomething2()),
Task.Factory.StartNew(() => GetSomething3())
};
var things = Task.WhenAll(tasks);

如何分别获取所有三个任务的结果并打印它们?

为了单独获得结果,您有多种方法,我会做这样的事情:

var task1  = GetSomething1();
var task2  = GetSomething2();
var task3  = GetSomething3();
// your method will continue when everything's completed, but you won't tie up a thread to just hang around until that time.
await Task.WhenAll(task1, task2, task3);
var result1 = await task1;
var result2 = await task2;
var result3 = await task3;

一种方法是让每个Task负责存储自己的结果,然后你所要做的就是await任务的集合。请注意,您必须使用await来使WhenAll()执行您传递给它的任务。

var results = new int[3];
var tasks = new[] {
Task.Factory.StartNew(() => results[0] = GetSomething1()), 
Task.Factory.StartNew(() => results[1] = GetSomething2()), 
Task.Factory.StartNew(() => results[2] = GetSomething3())
};
await Task.WhenAll(tasks);
Console.WriteLine(results[0]);
Console.WriteLine(results[1]);
Console.WriteLine(results[2]);

工作演示:https://dotnetfiddle.net/HS32QA

请注意,您可能需要小心使用例如List<T>而不是数组,然后调用list.Add(result),因为无法保证任务的执行顺序或何时完成。

你应该async..await模式与When一起使用,例如

private async Task MyExecution() {
var tasks = new[] {
//TODO: Task.Run is a better option than Task.Factory.StartNew
Task.Factory.StartNew(() => GetSomething1()),
Task.Factory.StartNew(() => GetSomething2()),
Task.Factory.StartNew(() => GetSomething3())
};
// Await until all tasks are completed 
await Task.WhenAll(tasks);
// Since all tasks are completed, we can (safely) query for their `Result`s:
var things = tasks
.Select(task => task.Result) // or task => await task
.ToArray();
// Let's print the things
for (int i = 0; i < things.Length; ++i) 
Console.WriteLine($"Task #{i + 1} returned {things[i]}");
... 
}

您是否考虑过实际使用异步函数?然后,您将拥有一系列包含结果的任务,并避免Task.Factory.StartNew的高度不可预测的行为。

private async Task MyExecution() 
{
var tasks = new[] {
GetSomething1(),
GetSomething2(),
GetSomething3()
};
// Await until all tasks are completed 
await Task.WhenAll(tasks);
foreach(var t in tasks){
//t.Result is available
}
}
public static async Task<int> GetSomething1() { return 1; }
public static async Task<int> GetSomething2() { return 2; }
public static async Task<int> GetSomething3() { return 3; }

在这里小提琴:https://dotnetfiddle.net/3ffs9L

最新更新