我測驗了兩段代碼:
僅供參考ldocs并IEnumerable<BsonDocument>呼叫doAmethodAsyncAPI。
var tasks = new List<(BsonDocument docs, int status, bool isSuccess)>>();
tasks.AddRange(ldocs.Select(async b => await doAmethodAsync())
result = await Task.WhenAll(tasks.toArray()).configuration(false)
tasks.RemoveAll(task => task.IsCompleted);
另一個相同,只有一個變化:
tasks.AddRange(ldocs.Select(b => doAmethodAsync())
我對 900 次回圈(6-8 秒)的性能沒有太大差異。
對我來說,正確的代碼是第二個,因為第一個它正在等待 API 的每一端。我這樣想是對的嗎?
uj5u.com熱心網友回復:
為簡化起見,您要問的是這之間的區別:
await Task.WhenAll(something.Select(async () => await DoSomethingAsync()).ToArray());
還有這個:
await Task.WhenAll(something.Select(() => DoSomethingAsync()).ToArray());
對我來說,正確的代碼是第二個,因為在第一個它等待api的每一端?
不,你誤解了它的作業方式。DoSomethingAsync()仍然會同時被呼叫,并且生成的任務仍然會同時完成。添加的 async/await 的唯一區別是編譯器將一些狀態機代碼添加到 lambda 函式中,以便如果拋出例外,該 lambda 將出現在您的堆疊跟蹤中。
與您使用的任何異步操作相比,來自該額外狀態機代碼的性能差異可以忽略不計。
讓堆疊跟蹤顯示異步方法呼叫發生的位置通常很有價值。在這種情況下,這可能沒什么大不了的,因為await Task.WhenAll()距離方法呼叫只有一行,所以關于如何DoSomethingAsync呼叫沒有歧義。但是您可以想象DoSomethingAsync從代碼的各個不同部分呼叫的場景,并以完全不同的方法等待生成的任務:如果該行代碼可能很難弄清楚是什么路徑導致了引發例外的點不包含在堆疊跟蹤中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/471249.html
