通过 Continuewith 捕获多个任务回调
Catch multiple Task callbacks via Continuewith
我想 运行 同时执行多个任务。每个任务都会 return 一个值类型。
谁能告诉我如何通过 ContinueWith
捕获所有回调?
我的测试代码:
static async Task<List<string>> ListAsync()
{
await Task.Delay(1000);
return new List<string>() { "Item 1", "Item 2" };
}
static async Task<int> IntAsync()
{
await Task.Delay(1000);
return 10;
}
static async Task<string> StringAsync()
{
await Task.Delay(1000);
return "My string";
}
static async Task Test()
{
Task t1 = StringAsync();
Task t2 = IntAsync();
Task t3 = ListAsync();
await Task.WhenAny(t1, t2, t3).ContinueWith(t =>
{
//how can I catch callbacks here?
});
}
如果不想调用不同continuation的任务,需要为每个task指定continuation:
static async Task Test()
{
Task t1 = StringAsync().ContinueWith(t => System.Console.Out.WriteLine("string"));
Task t2 = IntAsync().ContinueWith(t => System.Console.Out.WriteLine("int"));
Task t3 = ListAsync().ContinueWith(t => System.Console.Out.WriteLine("list"));
await Task.WhenAny(t1, t2, t3);
// use WhenAll if you want to wait until all tasks are done
}
WhenAny
将在任何子任务完成时完成,然后触发延续,因此延续只会被调用一次。
如果想在所有任务完成后调用一次回调,最简单的方法是这样:
static async Task Test()
{
Task t1 = StringAsync();
Task t2 = IntAsync();
Task t3 = ListAsync();
await Task.WhenAll(t1, t2, t3);
// your continuation logic here
}
如果您尝试检索所有任务的结果,一旦它们全部完成,您可以简单地使用 Task.WhenAll
。如果所有任务 return 结果相同,则 Task.WhenAll(Task[] 重载将 return 一个任务。在这种情况下,await Task.WhenAll
将 return 一个包含任务结果的数组,顺序为:
var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return 2});
var t3=Task.Run(()=>{...;return 3});
int[] results=await Task.WhenAll(t1,t2,t3);
//Check t1's result
Debug.Assert(results[0]==1);
当任务 return 的结果不同时, Task.WhenAll(params Task[]) 被调用其中 return 只是一个任务。您仍然可以访问每个任务的结果,使用它的 Result
属性 而没有任何阻塞的风险:
var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return "Hi"});
var t3=Task.Run(()=>{...;return new[]{1,2,3}});
await Task.WhenAll();
Debug.Assert(t2.Result=="Hi");
没有理由在使用 await
时使用 ContinueWith
,因为等待 与使用 ContinueWith
大致相同 - 它不'开始任何异步执行,它 等待而不阻塞 已经 运行 任务完成,它提取结果并将同步上下文设置为等待开始之前的状态。
我想 运行 同时执行多个任务。每个任务都会 return 一个值类型。
谁能告诉我如何通过 ContinueWith
捕获所有回调?
我的测试代码:
static async Task<List<string>> ListAsync()
{
await Task.Delay(1000);
return new List<string>() { "Item 1", "Item 2" };
}
static async Task<int> IntAsync()
{
await Task.Delay(1000);
return 10;
}
static async Task<string> StringAsync()
{
await Task.Delay(1000);
return "My string";
}
static async Task Test()
{
Task t1 = StringAsync();
Task t2 = IntAsync();
Task t3 = ListAsync();
await Task.WhenAny(t1, t2, t3).ContinueWith(t =>
{
//how can I catch callbacks here?
});
}
如果不想调用不同continuation的任务,需要为每个task指定continuation:
static async Task Test()
{
Task t1 = StringAsync().ContinueWith(t => System.Console.Out.WriteLine("string"));
Task t2 = IntAsync().ContinueWith(t => System.Console.Out.WriteLine("int"));
Task t3 = ListAsync().ContinueWith(t => System.Console.Out.WriteLine("list"));
await Task.WhenAny(t1, t2, t3);
// use WhenAll if you want to wait until all tasks are done
}
WhenAny
将在任何子任务完成时完成,然后触发延续,因此延续只会被调用一次。
如果想在所有任务完成后调用一次回调,最简单的方法是这样:
static async Task Test()
{
Task t1 = StringAsync();
Task t2 = IntAsync();
Task t3 = ListAsync();
await Task.WhenAll(t1, t2, t3);
// your continuation logic here
}
如果您尝试检索所有任务的结果,一旦它们全部完成,您可以简单地使用 Task.WhenAll
。如果所有任务 return 结果相同,则 Task.WhenAll(Task[] 重载将 return 一个任务。在这种情况下,await Task.WhenAll
将 return 一个包含任务结果的数组,顺序为:
var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return 2});
var t3=Task.Run(()=>{...;return 3});
int[] results=await Task.WhenAll(t1,t2,t3);
//Check t1's result
Debug.Assert(results[0]==1);
当任务 return 的结果不同时, Task.WhenAll(params Task[]) 被调用其中 return 只是一个任务。您仍然可以访问每个任务的结果,使用它的 Result
属性 而没有任何阻塞的风险:
var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return "Hi"});
var t3=Task.Run(()=>{...;return new[]{1,2,3}});
await Task.WhenAll();
Debug.Assert(t2.Result=="Hi");
没有理由在使用 await
时使用 ContinueWith
,因为等待 与使用 ContinueWith
大致相同 - 它不'开始任何异步执行,它 等待而不阻塞 已经 运行 任务完成,它提取结果并将同步上下文设置为等待开始之前的状态。