Mr.*_*oor 9 .net c# timer task-parallel-library async-await
对于发送到服务器的每个调用,我创建一个新的计时器Task.Delay来监视它的超时.
假设会有数百个并发呼叫.因此会有数百个Task计数器计时器.
我想TPL的内部实现考虑了这个场合,所有的任务都依赖于相同的底层计时器?
我不太了解Task.Delay内部工作的机制.
i3a*_*non 10
Task.Delay是用内部实现的System.Threading.Timer.该计时器类是单个本机计时器之上的包装器.要同步对该单个本机计时器的访问,可以AppDomain创建新计时器(并更改现有计时器)的级别锁定.您可以在参考源中看到:
internal bool Change(uint dueTime, uint period)
{
// ...
lock (TimerQueue.Instance)
{
// ...
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这很好,但是当你每秒创建相当数量的这些计时器时,你可以在该锁上获得重要的争用.实际知道的唯一方法是在真实环境中分析您的应用程序.
我个人已经通过CancellationTokenSource使用计时器创建了太多自我取消来达到这一点(你可以看到我在我的博客上避免这种情况:令人惊讶的争用System.Threading.Timer).
还有Stephen Toub的这篇文章关于来自Timeouts的Coalescing CancellationTokens提到:
"当然,总会出现推动性能界限的情况,我们最近看到了一些高吞吐量的情况,人们
CancellationToken每秒都会为成千上万的异步调用中的每一个创建一个这样的情况.这就是很多Timer和CancellationTokenSource实例."
如果近似延迟是可以接受的,另一种方法是Task.Delay用HashedWheelTimer替换。
代码示例。
HashedWheelTimer timer = new HashedWheelTimer();
await timer.Delay(1000);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1480 次 |
| 最近记录: |