zoukankan      html  css  js  c++  java
  • C# 各种定时器比较 zz

    1.单线程的定时器存在很多问题,定时器只是定时把消息WM_TIMER访到线程的消息队列里,但并不保证消息会立即被响应,如果碰巧系统比较忙,消息可能会在队列里放一段时间才被响应,这样会造成本来应该间隔一段时间发生的消息连续发生了。
    2. 。NET FrameWork带来了新的解决方案
    Server Timers System.Timers.Timer 基于服务器的计时器,位于"工具箱"的“组件”选项卡上
    Thread Timers System.Threading.Timer 在编程时使用的线程计时器
    Windows Timers System.Windows.Forms.Timer 基于 Windows 的标准计时器,"工具箱"的"Windows 窗体"选项卡上;
    • 区别a
      Windows Timers 提供了和WinAPI一样的Timer 基于消息,仍然是单线程
      其他两个是是基于线程池的Thread Pool【最大好处,产生的时间准确均匀】
    • 区别b
      Server Timers 和 Thread Timers 的不同在于ServerTimers 是基于事件的,Thread Timers是基于回调函数

    Thread Timer是一个轻量级的方便使用,但也要注意一些问题,由于是多线程定时器,就会出现如果一个Timer处理没有完成,到了时间下一个照样会发生,导致严重错误,对付重入问题,通常的办法是加锁,但对于Timer不能简单的这样处理。

    使用Timer来处于的事情,要注意:

    首先Timer处理里本来就不应该做太需要时间的事情,或者花费时间无法估计的事情,比同远方的服务器建立一个网络连接,这样的做法尽量避免
    如果实在无法避免,那么要评估Timer处理超时是否经常发生,如果是很少出现,那么可以用lock(Object)的方法来防止重入
    如果这种情况经常出现呢?那就要用另外的方法来防止重入了

    我们可以设置一个标志,表示一个Timer处理正在执行,下一个Timer发生的时候发现上一个没有执行完就放弃执行

    static int inTimer = 0;
    public static void threadTimerCallback(Object obj)
    {
    if ( inTiemr == 0 )
    {
    inTimer = 1;

    Console.WriteLine("Time:{0}, \tThread ID:{1}", DateTime.Now, Thread.CurrentThread.GetHashCode());
    Thread.Sleep(2000);

    inTimer = 0;
    }
    }

    但是在多线程下给inTimer赋值不够安全,还好Interlocked.Exchange提供了一种轻量级的线程安全的给对象赋值的方法

    static int inTimer = 0;
    public static void threadTimerCallback(Object obj)
    {
    if ( Interlocked.Exchange(ref inTimer, 1) == 0 )
    {
    Console.WriteLine("Time:{0}, \tThread ID:{1}", DateTime.Now, Thread.CurrentThread.GetHashCode());
    Thread.Sleep(250);

    Interlocked.Exchange(ref inTimer, 0);
    }
    }

    ====试验=======================================================
    1.ThreadTimer = new System.Threading.Timer(new TimerCallBack(onTime),this,0,1000)
    [- 参数 -]
    a.回调方法,
    b.回调方法中使用信息的对象,
    c.表示在 callback 参数调用它的方法之前延迟的时间量。指定 -1 毫秒以防止启动计时器。指定零 (0) 以立即启动计时器。
    d.在调用 callback 所引用的方法之间的时间间隔。指定 -1 毫秒可以禁用定期终止
    2.
    BaseTimeHandler 自定义一个事件
    void OnTime(Object State)
    {
    Control ctl = State as Form1;
    if ( ctl != null && BaseTimeHandler != null)
    {
    if ( ctl.IsHandleCreated )
    {
    DateTime dt = DateTime.Now;
    String DateString = dt.ToString("yyyy/MM/dd");
    String TimeString = dt.ToString("HH:mm:ss");

    string[] args = new string[]{DateString,TimeString};
    try
    {
    //如果在不同线程中
    if ( ctl.InvokeRequired )
    ctl.Invoke(BaseTimeHandler,args);
    else
    BaseTimeHandler(DateString,TimeString);
    }
    catch(Exception e)
    { }
    }
    }
    }
  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/avril/p/1545391.html
Copyright © 2011-2022 走看看