我正在尝试在每个异步任务完成时处理它们。这些任务有不同的结果集。我喜欢同时执行这些任务,但需要在任何任务完成时处理结果。
当异步函数具有相同的返回类型时,有很多 google 搜索结果,但是,我无法找到具有不同结果集的结果集。
private async Task CompleteTasksAsync()
{
var taskA = GetStringAsync();
var taskB = GetIntAsync();
var taskC = GetStringListAsync();
var taskD = GetGenericAsync<double>(1d);
//var tasks = new[] {taskA, taskB, taskC, taskD} // this will only work if all tasks have same return type
await Task.WhenAll(taskA, taskB, taskC, taskD); //This statement will wait until all tasks are completed
// when Task A finished Console.WriteLine(taskA.Result);
// when Task B finished Console.WriteLine(taskB.Result);
// when Task C finished Console.WriteLine(taskC.Result);
// when Task D finished Console.WriteLine(taskD.Result);
}
private Task<string> GetStringAsync() => Task.FromResult("string");
private Task<int> GetIntAsync() => Task.FromResult(1);
private Task<List<string>> GetStringListAsync() => Task.FromResult(new List<string> { "string"});
private Task<T> GetGenericAsync<T>(T data) => Task.FromResult(data);
Task.WhenAny
方法等待第一个任务完成,然后处理它的结果,将其从剩余任务列表中移除,重复直到所有任务完成。
private async Task CompleteTasksAsync()
{
var taskA = GetStringAsync();
var taskB = GetIntAsync();
var taskC = GetStringListAsync();
var taskD = GetGenericAsync<double>(1d);
var tasks = new List<Task> { taskA, taskB, taskC, taskD };
while (tasks.Count > 0)
{
var completedTask = await Task.WhenAny(tasks);
tasks.Remove(completedTask);
if (completedTask == taskA)
{
// we can't write `await completedTask` so we need to use original tasks with type parameter
Console.WriteLine(await taskA);
}
else if (completedTask == taskB)
{
Console.WriteLine(await taskB);
}
else if (completedTask == taskC)
{
var result = await taskC;
foreach (var item in result)
{
Console.WriteLine(item);
}
}
else if (completedTask == taskD)
{
Console.WriteLine(await taskD);
}
}
}
同样的事情还有另一种方法。您可以使用
Task
方法为每个
Task.ContinueWith
添加完成操作,然后等待所有任务完成。
Task.ContinueWith
创建一个在目标 Task
完成时异步执行的延续。
private async Task CompleteTasksAsync()
{
var taskA = GetStringAsync().ContinueWith(t => Console.WriteLine(t.Result));
var taskB = GetIntAsync().ContinueWith(t => Console.WriteLine(t.Result));
var taskC = GetStringListAsync().ContinueWith(t => Console.WriteLine(string.Join(",", t.Result)));
var taskD = GetGenericAsync<double>(1d).ContinueWith(t => Console.WriteLine(t.Result));
// Wait for all tasks to complete
await Task.WhenAll(taskA, taskB, taskC, taskD);
}