大量的计时器

Mas*_*Mas 12 .net c# timer

我需要编写一个接收事件的组件(事件具有唯一的ID).每个活动都要求我发出请求.该事件指定一个超时期限,等待来自请求的响应.

如果响应在计时器触发之前响起,那很好,我取消了计时器.如果计时器首先触发,那么请求超时,我想继续前进.

此超时时间是在事件中指定的,因此它不是常量.预期的超时时间在30秒到5分钟的范围内.

我可以看到实现这个的两种方法.

  1. 为每个事件创建一个计时器,并将其放入将事件链接到计时器的字典中.
  2. 创建一个包含超时DateTime的有序列表,以及每隔100ms循环一次的新线程,以检查是否超时.

选项1似乎是最简单的解决方案,但我担心创建这么多计时器可能不是一个好主意,因为计时器可能太昂贵了.在创建大量计时器时是否存在任何陷阱?我怀疑在后台,定时器实现可能实际上是选项2的有效实现.如果这个选项是个好主意,我应该使用哪个定时器?System.Timers.Timer或System.Threading.Timer.

选项2似乎更多的工作,与选项1相比可能不是一个有效的解决方案.

更新

我期望的最大定时器数量在10000的范围内,但更有可能在100的范围内.另外,正常情况是在发射之前取消定时器.

更新2

我使用10K实例运行测试,System.Threading.TimerSystem.Timers.Timer密切关注线程数和内存.System.Threading.TimerSystem.Timers.Timer通过内存使用判断相比,似乎"更轻" ,并且没有为两个定时器创建过多的线程(即 - 线程池正常工作).所以我决定继续使用System.Threading.Timer.

Fuz*_*ers 6

我在嵌入式系统(纯c)中经常执行此操作,因为我无法消耗大量资源(例如4k RAM是系统内存)。这是已成功使用的一种方法:

  1. 创建一个定期关闭(例如,每10 ms)的系统计时器(中断)。
  2. “计时器”是动态列表中的一项,指示在计时器关闭之前还剩下多少“滴答”。
  3. 每次系统计时器关闭时,迭代列表并递减每个“计时器”。每个为零的“解雇”。从列表中将其删除,然后执行计时器应该执行的任何操作。

计时器关闭时会发生什么情况取决于应用程序。可能是状态机开始运行。可能是一个函数被调用。可能是一个枚举,告诉执行代码如何使用向其发送“ Create Timer”调用的参数进行处理。计时器结构中的信息在设计中是必需的。“滴答计数”是秘密的调味料。

我们还创建了此函数,以返回计时器的“ ID”(通常是计时器结构的地址,该地址是从池中提取的),因此可以取消它或获取其状态。

便捷功能将“秒”转换为“滴答”,因此创建计时器的API始终以“秒”或“毫秒”为单位。

您可以将“ tick”间隔设置为合理的值,以进行粒度权衡。

我已经在C ++,C#,objective-C中完成了此操作的其他实现,而通用方法几乎没有变化。这是一个非常通用的计时器子系统设计/体系结构。您只需要一些东西来创建基本的“刻度”。

我什至使用紧密的“主”循环和高精度内部计时器的秒表来执行一次,以在没有计时器时创建自己的“模拟”刻度。我不推荐这种方法。我在一个简单的控制台应用程序中模拟硬件,但是没有访问系统计时器的权限,所以这是一个极端的情况。

在现代处理器上,每秒对数百个计时器列表进行10次迭代并不是一件大事。通过插入带有“增量秒”的项目并将它们按排序顺序放入列表中,您也可以通过多种方法来克服这一问题。这样,您只需要检查列表前面的那些即可。至少在迭代列表方面,这可以解决扩展问题。

这个有帮助吗?


dfe*_*aro 5

你应该用最简单的方法来做。如果您担心性能,您应该通过分析器运行您的应用程序并确定瓶颈。您可能会非常惊讶地发现这是一些您最意想不到的代码,并且您无缘无故地优化了您的代码。我总是尽可能编写最简单的代码,因为这是最简单的。请参阅过早优化

我不明白为什么大量计时器会出现任何陷阱。我们是在谈论十几个、100 个还是 10,000 个?如果它非常高,您可能会遇到问题。您可以编写一个快速测试来验证这一点。

至于要使用哪些 Timer 类:我不想窃取可能做了更多研究的其他人的答案:查看这个问题的答案`