繁体   English   中英

在其中任何一个完成后立即使用异步调用(具有不同的返回类型)的结果吗?

[英]Consume the result of async calls (with different return type) as soon as any one of them is done?

以下代码启动T1Async()T2Async()T3Async()T4Async()并等待它们全部完成,然后再使用这些调用的结果。 但是,运行这些异步调用的时间可以随机地很短或很长。

Task<int> T1Async() { };
Task<string> T2Async() { };
Task<ClassX> T3Async() { };
Task<ClassY> T4Async() { };

var t1 = T1Async();
var t2 = T2Async();
var t3 = T3Async();
var t4 = T4Async();

var v1 = await t1;
var v2 = await t2;
var v3 = await t3;
var v4 = await t4;
// Or Task.WhenAll(new Task[] { t1, t2, t3, t4 });

UseV1(v1); // Want these calls be run asap
UseV2(v2);
UseV3(v3);
UseV4(v4);

UseAll(v1, v2, v3, v4); // Need all the result here

如何在调用完成后立即使用结果并确保所有结果都被使用?

因此,您希望并行执行UseVX任务,但是要等待所有(不同类型的)结果,以便将其传递给UseAll方法。

使用Task.Run

var t1 = Task.Run(async () => { var x = await T1(); UseV1(x); return x; });
var t2 = Task.Run(async () => { var x = await T2(); UseV2(x); return x; });
var t3 = Task.Run(async () => { var x = await T3(); UseV3(x); return x; });
var t4 = Task.Run(async () => { var x = await T4(); UseV4(x); return x; });
await Task.WhenAll(t1, t2, t3, t4);
UseAll(t1.Result, t2.Result, t3.Result, t4.Result);

使用ContinueWith

var t1 = T1().ContinueWith(x => { UseV1(x.Result); return x.Result; });
var t2 = T2().ContinueWith(x => { UseV2(x.Result); return x.Result; });
var t3 = T3().ContinueWith(x => { UseV3(x.Result); return x.Result; });
var t4 = T4().ContinueWith(x => { UseV4(x.Result); return x.Result; });
await Task.WhenAll(t1, t2, t3, t4);
UseAll(t1.Result, t2.Result, t3.Result, t4.Result);

要同时运行异步代码,请使用Task.WhenAll 要在每个操作完成时执行一个方法,请引入一个新的async方法

async Task<int> T1AndUseV1Async() { var v1 = await T1Async(); UseV1(v1); return v1; };
async Task<string> T2AndUseV2Async() { var v2 = await T2Async(); UseV2(v2); return v2; };
async Task<ClassX> T3AndUseV3Async() { var v3 = await T3Async(); UseV3(v3); return v3; };
async Task<ClassY> T4AndUseV4Async() { var v4 = await T4Async(); UseV4(v4); return v4; };

var t1 = T1AndUseV1Async();
var t2 = T2AndUseV2Async();
var t3 = T3AndUseV3Async();
var t4 = T4AndUseV4Async();

await Task.WhenAll(t1, t2, t3, t4);

UseAll(await t1, await t2, await t3, await t4);

一个可测试的案例:

async Task<int> T1() { return await Task.FromResult(1); }
async Task<string> T2() { return await Task.FromResult("T2"); }
async Task<char> T3() { await Task.Delay(2000); return await Task.FromResult('A'); }
async Task<string> T4() { return await Task.FromResult("T4"); }

var t1 = T1().ContinueWith(x => { Console.WriteLine($"Use T1: {x.Result}"); return x.Result; });
var t2 = T2().ContinueWith(x => { Console.WriteLine($"Use T2: {x.Result}"); return x.Result; });
var t3 = T3().ContinueWith(x => { Console.WriteLine($"Use T3: {x.Result}"); return x.Result; });
var t4 = T4().ContinueWith(x => { Console.WriteLine($"Use T4: {x.Result}"); return x.Result; });
await Task.WhenAll(t1, t2, t3, t4);
Console.WriteLine("Done");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM