我正在编写一个需要使用的应用程序 Timers,但可能很多。可扩展性如何 System.Threading.Timer 班级?该文档只是说它是“轻量级的”,但没有进一步解释。这些计时器是否会被吸入一个代表某个线程(或非常小的线程池)处理所有回调的线程中? Timer, ,或者每个 Timer 有自己的线程吗?

我想改写这个问题的另一种方式是:怎么 System.Threading.Timer 实施的?

有帮助吗?

解决方案

我这样说是为了回答很多问题:不要忘记框架的(托管)源代码是可用的。您可以使用此工具来获取全部内容: http://www.codeplex.com/NetMassDownloader

不幸的是,在这种特定情况下,很多实现都是在本机代码中,因此您无法查看它......

不过,他们肯定使用池线程而不是每个计时器线程。

实现大量计时器的标准方法(这是内核在内部执行此操作的方式,我怀疑间接地是大型计时器集合的最终结果)是维护按时间排序的列表,直到到期 - 所以系统只需要担心检查下一个即将到期的计时器,而不是整个列表。

粗略地说,启动计时器的时间复杂度为 O(log n),处理正在运行的计时器的时间复杂度为 O(1)。

编辑:刚刚在看杰夫·里克特的书。他说(Threading.Timer)它对所有 Timer 对象使用单个线程,该线程知道下一个计时器(即何时)如上所述)到期并根据需要调用 ThreadPool.QueueUserWorkItem 进行回调。这样做的效果是,如果您在下一个回调到期之前没有完成计时器上的一个回调服务,您的回调将重新进入另一个池线程。所以总而言之,我怀疑您会看到拥有大量计时器的大问题,但是如果大量计时器在同一个计时器上触发和/或它们的回调运行缓慢,您可能会遇到线程池耗尽的问题。

其他提示

我认为您可能想要重新考虑您的设计(也就是说,如果您自己可以控制设计)。如果您使用了如此多的计时器,这实际上是您所关心的,那么显然存在一些整合的潜力。

这是几年前 MSDN 杂志上的一篇好文章,比较了三个可用的计时器类,并深入了解了它们的实现:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

巩固它们。创建计时器服务并要求计时器。它只需要保留1个主动计时器(对于下一个应呼叫)...

为了使这比仅仅创建大量 Threading.Timer 对象有所改进,您必须假设这并不完全是 Threading.Timer 内部已经在做的事情。我很想知道你是如何得出这个结论的(我没有分解框架的本机部分,所以你很可能是对的)。

^^ 正如 DannySmurf 所说:巩固它们。创建一个计时器服务并请求计时器。它只需要保留 1 个活动计时器(用于下一次到期调用)和所有计时器请求的历史记录,并在 AddTimer() / RemoveTimer() 上重新计算。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top