BlockingCollection循环Add结合await耗时远超预期问题排查
问题复现与原因说明
最简复现代码
这是一个控制台应用,核心逻辑如下:
- 创建有界的
BlockingCollection<int>,容量设为1000 - 启动后台线程通过
TryTake方法消费集合中的项 - 主线程执行如下循环,向集合中添加项直到达到容量上限,同时测量耗时:
// 测量每次Add间隔1毫秒时添加项的耗时 var sw = Stopwatch.StartNew(); for (int i = 0; i < collection.BoundedCapacity; i++) { collection.Add(i); await Task.Delay(millisecondsDelay: 1); } sw.Stop();
实际表现与预期不符
按照逻辑,每次添加后延迟1毫秒,1000次循环理论耗时不应超过1秒,但实际情况:
- 调试状态下,循环耗时3.2-4秒
- 无调试状态下,耗时高达15-16秒
远超预期的2*BoundedCapacity毫秒上限。
对比测试
如果注释掉代码中的await Task.Delay(millisecondsDelay: 1)语句,程序表现正常,循环仅需数毫秒即可完成。
问题根源
经确认,该问题的核心原因是Windows系统的定时器分辨率约为15毫秒——Task.Delay(1)实际会等待系统定时器的最小间隔,而非精确的1毫秒,累积下来导致总耗时大幅增加。(感谢Simon Kocourek的解答)
内容的提问来源于stack exchange,提问作者Palo Mraz
相关产品推荐
相关产品推荐

