CLR via C#(第3版):.net中的定时器整理总结

这几天由于项目中设计到用定时器实时调用webserver获取数据,开始想到用线程,但是由于webservice返回太慢,上一个线程无法结束,下个线程无法开启。出现假死的情况。所以考虑使用定时器,这样每次不管webserver调用结果是否返回,直接执行定时启动下一个任务。达到实时刷新的目的.本文通过CLR via C#(第3版)整理学习出来。

(一)定时器总结:
(1)System.Threading的Timer类:要在一个线程池上执行定时的(周期性发生的)后台任务时,它是最好的定时器
(2)System.Windows.Forms的Timer类:构造这个类的一个实例,相当于告诉Windows将一个定时器和调用线程关联(参见Win32_SetTimer)。这个定时器出发时,Windows将一条计时器消息(WM_TIMER)注入线程的消息队列。线程必须将执行消息泵提出这些消息,并把它们派遣给想要的回调方法。注意,这里的工作都有一个线程完成---设置计算器的线程保证就是执行回调方法的线程,这还意味着你的计时器不会由多个线层并发执行
(3)System.Windows.Threading的DispatcherTimer类:这个是System.Windows.Forms的Timer类在在silverlight 和WPF中的等价物。
(4)System.Timers的Timer类:基本上是System.Threading的Timer类的包装。这个类应该删除。除非真的想在设计平面中添加一个计时器。

(二)代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace TimerDemo
{
    /// <summary>
    /// 定时器总结:
    /// (1)System.Threading的Timer类:要在一个线程池上执行定时的(周期性发生的)后台任务是时,它是最好的定时器
    /// (2)System.Windows.Forms的Timer类:Windows将一个定时器和死奥用线程关联。计时器消息注入线程队列。执行消息泵提出这些消息
    /// (3)System.Windows.Threading的Timer类:这个是System.Windows.Forms的Timer类在在silverlight 和WPF中的等价物
    /// (4)System.Timers的Timer类:基本上是System.Threading的Timer类的包装。这个类应该删除。除非真的想在设计平面中添加一个计时器。
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            //TestDemo1();
            TestDemo2();
            Console.ReadLine();
        }

        #region TestDemo1
        public static int i = 1;
        private static void TimerCallback(object o)
        {
           
            Debug.WriteLine("调用第{0}次",i);
            Console.WriteLine("In TimerCallback: "+DateTime.Now);
            GC.Collect();
            i++;
        }
        private static void TestDemo1()
        {
            Timer t = new Timer(TimerCallback, null, 0, 2000);
            Console.ReadLine();
            //由于ReadLine之后引用t(会被被优化掉)
            //因为JIT编译器是一个优化的编译器,将局部变量或参数设为null。
            //换言之JIT编译器会将t=null整行代码删除(优化掉)
            //所以回调放在Debug情况下会方法会被调用多次,而在Release下只调用一次
            //t = null;
            //t.Dispose();
        }
        #endregion

        #region
        //构造一个Timer类的实例相当于告诉线程池:在将来某个时间(具体由你定)回调你的一个方法
        //在内部,线程池为所有的Timer对象只是用一个线程。这个线程知道下一个Timer对象什么时候到期(计时器还有多久触发)
        //下一个Timer对象到期时,在内部调用ThreadPool的QueueUserWorkItem.将一个工作项添加到线程池的队列中,使你的回调方法得到回到。
        private static Timer s_Timer;
        private static void TestDemo2()
        {
            Console.WriteLine("Main thread: starting a timer");
            using(s_Timer=new Timer(ComputeBoundOP,5,0,Timeout.Infinite))
            {
                Console.WriteLine("Main thread: Doing other work here...");
                Thread.Sleep(1000);
            }//现在用Dispose取消计时器
        }
        private static void ComputeBoundOP(object state)
        {
            //这个方法由一个线程池线程执行
            Console.WriteLine("In ComputerBondOp:state={0}",state);
            //模拟其他工作
            Thread.Sleep(1000);
            //让Timer在2秒后再调用这个方法
            s_Timer.Change(2000, Timeout.Infinite);
            //这个方法返回时,线程回归池中,等待下一个工作项
        }
        #endregion
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值