Acettest's Blogs

Think Different

定时器问题

System.Threading.Timer
它让线程池线程定时调用一个方法。

public sealed class Timer:MarchalByRefObject,IDisposable{
    public Timer(TimerCallback callback, Object state, Int32 dueTime, Int32 period);
    public Timer(TimerCallback callback, Object state, UInt32 dueTime, UInt32 period);
    public Timer(TimerCallback callback, Object state, Int64 dueTime, Int64 period);
    public Timer(TimerCallback callback, Object state, Timespan dueTime, Timespan period);
}

参数:

  1. callback
    delegate void TimerCallback(Object state);
  2. state
    向委托传参,无参数时传null
  3. dueTime
    首次调用回调方法时应该等待多少毫秒,如果希望回调方法被立即调用,传0即可
  4. period
    回调方法的回调周期,每经过多长时间调用一次回调方法,传Timeout.Infinite,回调方法只被调用一次。

说明的几个问题:

  • System.Threading.Timer内部是使用线程池的
  • 定时器的触发周期小于回调方法的执行耗时,导致定回调方法被同时调用多次的解决方法
    构造Timer时,为period参数指定Timeout.Infinite。这样,计时器就只触发一次,然后,在你的回调方法中,调用Change方法来指定一个新的dueTime,并再次为period参数指定Timeout.Infinite
  • 如果有需要定时执行的操作,可利用Task的静态Delay方法和C#的async和await关键字来编码
  • 定时器只执行一次的可能原因
    有可能是c#垃圾回收机制导致定时器被提前回收了,若没有任何对象引用timer,则timer有可能被回收。所以需要合适的地方添加timer.Dispose()来持有对timer的引用
    采用Debug进行调试(因为默认情况下,Debug模式未启用JIT编译器优化,如果启用了,需要关闭),如果定时器能周期执行,但是在Release下不能定期执行,那么就是定时器被定期回收了

  • 用法代码地址:https://github.com/Acettest/TimerDemo/tree/master/TimerDemo

阅读更多
个人分类: C#
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭