使用计时器经常创建单个超时

时间:2012-08-24 11:02:01

标签: c# timer

我正在处理超时,该超时设置为在经过一段时间后发生,之后我想收到一个回调。现在我正在使用Timer这样做,当被解雇时自行处理。

public class Timeouter
{
    public void CreateTimeout(int timeout, Action onTimeout)
    {
        Timer t = null;
        t = new Timer(_ =>
            {
                onTimeout();
                t.Dispose();
            }, new object(), timeout, Timeout.Infinite);    
    }
}

我对此计时器的资源使用有点担心,因为它可能会被频繁调用,因此会设置很多计时器来解雇一次并自行处理。考虑到计时器是IDisposable,它会向我表明它确实使用某种昂贵的资源来完成它的任务。

  • 我是否过多地担心Timer的资源使用情况,或者解决方案可能没问题呢?
  • 我还有其他选择吗?有一个计时器并摆弄它的频率并根据需要停止它以便容纳其中几个超时会更好吗?任何其他可能更轻量级的选项让任务在经过一段时间后执行一次

4 个答案:

答案 0 :(得分:1)

虽然它不是答案,但由于篇幅我把它作为答案添加。

在服务器/客户端环境中,在服务器上使用Timers的AFAIK不是最好的方法,相反,如果你有胖客户端甚至是瘦客户端,你应该在客户端设计一些轮询机制,如果它想要执行某个操作自己的服务器(因为客户端在设置定时器之后可能会断开连接,然后重新实例化并再次设置定时器,导致服务器在将来的某个时间不可用(潜在的DOS攻击)),

或者想一个单一的计时器策略来处理所有客户端,它实现了滑动过期或客户特定策略来处理它。

答案 1 :(得分:1)

另一个选项是维护一个已排序的事物的排序列表,将它们的到期时间而不是它们的持续时间添加到列表中,保持列表按到期时间排序,然后只从列表中弹出第一项什么时候到期。

您当然需要在辅助线程上调用大部分内容并调用您的回调。你也不需要保持线程旋转,你可以在add方法上设置一个等待句柄,其超时设置为(稍微小于)持续时间,直到下一个超时到期为止。有关等待超时的更多信息,请参阅here

我不知道这是否比创建大量计时器更好。

答案 2 :(得分:1)

.Net有2或3个定时器类,价格昂贵。但是,您使用的System.Threading.Timer类非常便宜。此类不使用内核资源或将线程置于休眠状态等待超时。相反,它只为所有Timer实例使用一个线程,因此您可以轻松拥有数千个计时器,并且仍然可以获得微小的处理器和内存占用。您必须仅调用Dispose,因为您必须通知系统停止跟踪某个计时器实例,但这并不意味着这是一个昂贵的类/任务。 一旦达到超时,该类将调度回调由ThreadPool线程执行,因此它不会启动新线程或类似的东西。

答案 3 :(得分:1)

创建一个可以许多间隔时间的便宜计时器非常简单。您只需一个计时器。将其设置为最接近的截止时间。当它滴答时,为每个到期的计时器触发回调或事件。然后重复一遍,再次查看下一个截止时间的活动计时器列表。如果计时器更改其间隔,则只需再次重复搜索。

回调可能会发生一些可能很昂贵的事情。解决这个问题的最佳方法是在线程池线程上运行该代码。

这是非常节俭地使用系统资源,只有一个计时器和最便宜的线程。无论何时计时器的状态发生变化,你需要花费一点开销,为了查看活动计时器列表的O(n)复杂性,你可以使用SortedList来完成大部分O(log(n))。但是哦很小。

您可以自己轻松编写代码。

但是你没必要,System.Timers.Timer 已经按照这种方式运行。不要帮忙。