问题描述
我已经找到了很多相关内容,这些内容全都花哨了,而我却一直找不到答案.我几乎100%确信 Task.Delay(int)
不使用线程,因为我可以在只有16个逻辑处理器的计算机上运行此代码:
I've found a ton of related content that all beat around the bush and I've never been able to find an answer. I'm almost 100% certain that Task.Delay(int)
does not use a thread, because I can run this code on my machine with only 16 logical processors:
var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);
这需要十秒钟才能完成.我认为,如果使用大约十万个线程,则将花费更长的时间.
And it takes ten seconds to complete. If it were using roughly a hundred thousand threads it would take quite a bit longer, I'd think.
所以我的问题是 Task.Delay(int)
如何工作?不是表示,但从线程和硬件资源的角度来看.
So my question is how does Task.Delay(int)
work? Not in the manner that this poorly-entitled SO question indicates, but from a threading and hardware resources standpoint.
推荐答案
在.NET的当前实现中,只有一个计时器线程"(timer thread).只是跟踪托管计时器实例,并在适当的时间引发事件.此计时器线程将在其控制信号上阻塞,并将超时设置为下一个计时器的到期时间.控制信号用于添加/删除/更改计时器,因此当此阻塞请求超时时,计时器线程会知道下一个计时器已触发.这是正常的线程阻塞操作,因此在内部,线程将被空闲并从调度程序队列中删除,直到该阻塞操作完成或超时.这些操作的超时由操作系统调度程序的计时器中断处理.
In the current implementation of .NET, there is a single "timer thread" that just keeps track of managed timer instances and raises their events at the appropriate times. This timer thread will block on its control signal with a timeout set to the next timer's due time. The control signal is used to add/remove/change timers, so when this blocking request times out, the timer thread knows the next timer has fired. This is a normal thread blocking operation, so internally, the thread is idled and removed from the scheduler queue until that blocking operation completes or is timed out. The timing out of those operations is handled by the OS scheduler's timer interrupt.
因此从技术上讲,有一个线程,但是每个进程只有一个线程,而不是每个 Task.Delay
都有一个线程.
So technically there is a thread, but it's only one thread per process, not one thread per Task.Delay
.
我再次强调,这是.NET的当前实现中的内容.已经提出了其他解决方案,例如每个CPU一个计时器线程,或计时器线程的动态池.也许他们由于某种原因被试验并被拒绝,或者将来会采用替代解决方案.AFAIK尚未在任何地方正式记录下来,因此这是一个实现细节.
I again stress that this is in the current implementation of .NET. Other solutions have been proposed, such as one timer thread per CPU, or a dynamic pool of timer threads. Perhaps they were experimented with and rejected for some reason, or perhaps an alternative solution will be adopted in the future. AFAIK this is not officially documented anywhere, so this is an implementation detail.
这篇关于Task.Delay是否真的像I/O操作一样是异步的,即它是否依赖硬件和中断而不是线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!