C#/.NET中Task.WhenAll是否存在不必要延迟?执行时间突刺原因
Task等待离散时间突刺与Task.WhenAll性能异常问题
- 等待Task完成时出现离散执行时间突刺的成因是什么?
- 为何
Task.WhenAll的执行速度,反而不如10ms间隔循环轮询检查所有任务完成状态的方案? - 调用
Task.WhenAll时观测到无明确诱因的延迟,测试发现NativeAOT模式下该现象受影响程度较低,初步怀疑该问题是否与不必要的JIT编译行为相关?
测试观测结果
不同睡眠线程数下的执行时间测试图表:
注:上述所有测试数据均通过命令行运行独立自包含exe采集得到。
最初怀疑问题由垃圾回收(GC)导致,但在Visual Studio中运行测试时,VS诊断工具未显示任何垃圾回收标记,已排除该猜想:
补充更新测试结论:将测试逻辑中的Thread.Sleep替换为真实CPU负载后,两种方案的性能差异和离散突刺现象均完全消失:
问题复现代码
using System.Diagnostics; namespace ConsoleApp1 { internal class Program { static async Task Main() { for (int i = 1; i <= 100; i+=1) { await RunTest(i); } } public static async Task RunTest(int count) { var sw = Stopwatch.StartNew(); var tasks = new List<Task>(); // 构造已启动的任务 for (int i = 0; i < count; i++) { tasks.Add(Task.Run(() => Thread.Sleep(250))); } // 测试1:使用Task.WhenAll //await Task.WhenAll(tasks); // 测试2:10ms间隔循环轮询 bool completed = false; while (!completed) { await Task.Delay(10); completed = tasks.All(t => t.IsCompleted); } Console.WriteLine($"{count},{sw.Elapsed.TotalSeconds}"); } } }
内容的提问来源于stack exchange,提问作者Beau Gosse
相关产品推荐
相关产品推荐

