繁体   English   中英

为什么Task.WhenAll偶尔需要很长时间

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

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