2008-08-28 42 views
26

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

我想用另一种方法来重述这个问题是:System.Threading.Timer如何实现?

回答

29

我说,这响应了很多问题:不要忘记框架的(托管)源代码可用。您可以使用此工具来得到这一切:http://www.codeplex.com/NetMassDownloader

不幸的是,在这种特定的情况下,大量的执行是在本机代码,所以你不要看它......

他们不过,必须使用线程池而不是每个线程。

实现大量计时器的标准方法(这是内核如何在内部完成的,我怀疑是间接如何定时器的大集合的结果)是维护按时间排序的列表,到期 - 所以系统只需要担心检查即将到期的下一个计时器,而不是整个列表。大致上,这给出了用于启动定时器的O(log n)和用于处理运行定时器的O(1)。

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

+0

优先级队列可能比排序列表更有效,除非所有定时器在开始时被批量添加,然后排序,并且以后不再添加更多定时器。 – RAL 2010-02-25 04:39:15

7

我想你可能想重新考虑你的设计(也就是说,如果你自己可以控制设计)。如果你使用这么多定时器,这实际上是你的关注点,那么显然有一些潜在的整合潜力。

下面是从MSDN杂志从几年前的一篇好文章,这三个可用的定时器类进行比较,并给出了一些洞察他们的实现:

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

0

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

5

合并它们。创建一个定时器 服务并请求定时器。 它将只需要保持1个活跃 定时器(今后由于调用)...

为这是一种改进过刚刚创建大量Threading.Timer的对象,你必须假设它不是这正是Threading.Timer已经在内部完成的事情。我有兴趣知道你是如何得出这个结论的(我没有反编译框架的本地部分,所以你可能是对的)。