Like performance when there are hundreds of Task.Delay

For each call that goes to the server, I create a new Task.Delay timer to view its timeout.

Say there will be hundreds of simultaneous calls. Consequently, there will be a hundred Task counting timer.

I assume that the internal implementation of TPL considered this case, and all tasks are based on the same timer?

I do not quite understand the mechanism of how Task.Delay works internally.

+5
source share
1 answer

Task.Delay is implemented with internal System.Threading.Timer . This timer class is a wrapper on top of one built-in timer. To synchronize access to this single built-in timer, lock the AppDomain level to create new timers (and modify existing ones). You can see this in the reference source :

 internal bool Change(uint dueTime, uint period) { // ... lock (TimerQueue.Instance) { // ... } // ... } 

In most cases, this is normal, but when you create a significant amount of these timers per second, you can get serious competition in this lock. The only way to learn how to profile your application in a real environment .


I personally reached this point by creating too many self-curing CancellationTokenSource using timers (you can see how I avoided this on my blog: An amazing conflict in System.Threading.Timer ).

There's also this Steven Tuub post on Coalescing CancellationToken from Timeouts , which mentions:

β€œOf course, there are always scenarios that push the boundaries of performance, and recently seen some high-performance cases where people created one such CancellationToken for each of the thousands and thousands of asynchronous calls per second . These are many instances of Timer and CancellationTokenSource .

+9
source

All Articles