簡體   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