C# 通过Continuewith捕获多个任务回调
我想同时运行多个任务。每个任务都将返回一个值类型 谁能告诉我如何通过C# 通过Continuewith捕获多个任务回调,c#,.net,task,C#,.net,Task,我想同时运行多个任务。每个任务都将返回一个值类型 谁能告诉我如何通过ContinueWith捕获所有回调 我的测试代码: static async Task<List<string>> ListAsync() { await Task.Delay(1000); return new List<string>() { "Item 1", "Item 2" }; }
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?
});
}
静态异步任务ListAsync()
{
等待任务。延迟(1000);
返回新列表(){Item 1”,“Item 2};
}
静态异步任务IntAsync()
{
等待任务。延迟(1000);
返回10;
}
静态异步任务StringAsync()
{
等待任务。延迟(1000);
返回“我的字符串”;
}
静态异步任务测试()
{
任务t1=StringAsync();
任务t2=IntAsync();
任务t3=ListAsync();
等待任务。在任何时候(t1、t2、t3)。继续(t=>
{
//我怎么能在这里接到回电?
});
}
如果不想调用具有不同延续性的任务,则需要为每个任务指定延续性:
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.whalll
。如果所有任务返回相同的结果,则重载将返回一个任务。在这种情况下,wait Task.whalll
将按顺序返回包含任务结果的数组:
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);
当任务返回不同的结果时,调用只返回任务的。但是,您仍然可以使用其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");
当使用
wait
时,没有理由使用ContinueWith
,因为wait的作用与使用ContinueWith
大致相同-它不会启动任何异步执行,它会无阻塞地等待已经运行的任务完成,它提取结果,并将同步上下文设置为等待开始之前的状态。为什么不使用任务。当所有时?你为什么要把ContinueWith
和wait
混在一起?@Luizgrs这是个非常糟糕的主意-。结果块。此外,完全没有理由这样做,因为任务完成后,wait
会返回结果,这是您误解的。你为什么要使用ContinueWith
?只要做等待任务即可(t1、t2、t3)编码>就完成了。@幸运的是编码问题是继续进行
,而不是等待
。只需调用var results=wait Task.WhenAll(t1、t2、t3)
并检查任务的结果取决于您想对其执行的操作。如果您只是想以某种方式处理它们中的每一个,您不需要任务;var result2=等待t2;var result3=等待t3代码>。如果您在所有
时都使用了,您只需在之后使用t1.result
等读取结果即可。当然,Task.whalll
会返回所有任务,因此如果需要对所有任务执行相同的操作,只需在结果上为每个
构建一个foreach
。当任何
将按顺序返回任务的结果时,没有理由使用这样的代码-,将ContinueWith
与async/await
混合在一起似乎很奇怪。对我来说,这通常是一个或另一个决定,对后者有强烈的偏见。我相信OP认为,当任何人以某种方式循环完成所有任务时,但我不想偏离原来的问题太远,对不起,但是在你的例子中,有没有另一种方法可以将3个ContinueWith
组合成1行而不是3行呢?这就是为什么我把wait
放在ContinueWith
之前的原因。是的,我更喜欢这种方法而不是使用foreach
。我能有一个小问题吗?我注意到您说的关于ContinueWith
:`它提取结果并将同步上下文设置为等待启动之前的状态。为什么不将结果
t1.Result
或t2.Result
或t3.Result
作为演示?