[英]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.