[英]Why does Task.WhenAll occasionally take a long time
我有一個運行少量請求的ASP.NET站點(在3台服務器上分配約500 rpm的請求),通常這些請求大約需要15毫秒。 但是,我發現經常有一些請求花費更長的時間(1秒或更長時間)。 我已將延遲范圍縮小到對Task.WhenAll
的調用。 這是令人反感的代碼的示例:
var taskA = dbA.GetA(id);
var taskB = dbB.GetB(id);
var taskC = dbC.GetC(id);
var taskD = dbD.GetD(id);
await Task.WhenAll(taskA, taskB, taskC, taskD);
每個單獨的任務都經過測量,耗時不到10ms。 我已經將延遲確定為Task.WhenAll
調用,這似乎與任務的計划方式有關。 據我所知,TPL任務池沒有太大壓力,所以我對性能如此零散的原因感到困惑。
創建線程會增加開銷。 根據您的操作,您還可以嘗試Parallel.ForEach。
public static void yourMethod(int id){
var tasks = new List<IMyCustomType> { new dbA.GetA(id), new dbB.GetB(id), new dbC.GetC(id), new dbD.GetD(id)};
// Your simple stopwatch for timing
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
// For each 'tasks' list item, call 'executeTasks' (Max 10 occurrences)
// - Processing for all tasks will be complete before
// continuing processing on the main thread
Parallel.ForEach(tasks, new ParallelOptions { MaxDegreeOfParallelism = 10 }, executeTasks);
stopWatch.Stop();
Console.WriteLine("Completed execution in: " + stopWatch.Elapsed.TotalSeconds);
}
private static void executeTasks(string obj)
{
// Your task's work here.
}
異步操作涉及上下文切換,這非常耗時。 不幸的是,並非總是以確定性的方式。 為了加快處理速度,請嘗試為Task.WhenAll調用添加ConfigureAwait(false)前綴,如下所示:
await Task.WhenAll(taskA, taskB, taskC, taskD).ConfigureAwait(false);
這將消除額外的上下文切換,這實際上是服務器端應用程序推薦的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.