我正在处理超时,该超时设置为在经过一段时间后发生,之后我想收到一个回调。现在我正在使用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
的资源使用情况,或者解决方案可能没问题呢?答案 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 已经按照这种方式运行。不要帮忙。