C# 三个Timer

在C#中存在3种经常使用的 Timer服务器

  1. System.Windows.Forms.Timer
  2. System.Timers.Timer
  3. System.Threading.Timer

零、System.Windows.Forms.Timer

这个 Timer 是单线程的,也就是说只要它运行,其余线程就要等着。
ZElKBR.gif多线程

这个 Timer 有以下特色:函数

  1. 彻底基于UI线程,定时器触发时,操做系统把定时器消息插入线程消息队列中,调用线程执行一个消息泵提取消息,而后发送到回调方法Tick中;
  2. 使用 StartStop 启动和中止 Timer;
  3. UI操做过长会致使 Tick 丢失;
  4. 可使用委托Hook Tick事件;
  5. 精确度不高;
  6. 经过将 Enabled 设置为 True,使 Timer 自动运行

从上面的第一个特色能够得知,该 Timer 会形成 WinForm UI 假死,所以若是须要定时处理大量计算或者大量IO操做的任务,不建议使用该 Timer ,接下来咱们看一个例子体会一下在IO操做的状况下出现的假死状况:this

咱们在Form中放入两个Button 一个Lable和一个Timer
ZetMuV.pngspa

private void Button_Click(object sender, EventArgs e)
{
    timer.Interval = 1000;
    timer.Tick += Timer_Tick;
    timer.Start();
}

private void Timer_Tick(object sender, EventArgs e)
{
    for (int i = 0; i < 10000; i++)
    {
        File.AppendAllText(Directory.GetCurrentDirectory()+"test.txt", i.ToString());
        this.label_output.Text = "当前操做:插入数字" + i;
    }
}

咱们单击计算按钮,咱们会发现WinForm出现了假死(没法移动窗口、按钮没法点击等)操作系统

1、System.Timers.Timer

该 Timer 是基于服务器的计时器,是为在多线程环境中用于辅助线程而设计的,能够在线程间移动来处理引起的 Elapsed 事件,比上一个计时器更加精确。线程

该 Timer 有以下特色:设计

  1. 经过 Elapsed 设置回掉处理事件,且 Elapsed 是运行在 ThreadPool 上的;
  2. 经过 Interval 设置间隔时间;
  3. AutoReset 设置为 False 时,只在到达第一次时间间隔后触发 Elapsed 事件;
  4. 是一个多线程计时器;
  5. 没法直接调用 WinForm 上的控件,须要使用 委托
  6. 主要用在 Windows 服务中。

一样咱们经过代码来看一下该 Timer 计时器怎么使用:code

System.Timers.Timer timersTimer = new System.Timers.Timer();
private void Button_Click(object sender, EventArgs e)
{
    timersTimer.Interval = 1000;
    timersTimer.Enabled = true;
    timersTimer.Elapsed += TimersTimer_Elapsed;
    timersTimer.Start();
}

private void TimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    for (int i = 0; i < 10000; i++)
    {
        this.BeginInvoke(new Action(() =>
        {
            this.label_output.Text="当前时间:"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }), null);
    }
}

private void Button1_Click(object sender, EventArgs e)
{
    timersTimer.Stop();
}

运行上面代码,会发现WinForm界面假死的状况消失了。orm

2、System.Threading.Timer

该 Timer 一样也是一个多线程的计时器,它有以下特色:

  1. 多线程
  2. 和前两个计时器相比没有 StartStop 方法,若是要中止计时器,必须调用 Dispose 方法来销毁 Timer 对象;
  3. 调用 Dispose 方法后并不能立刻中止全部的计时器,这是由于间隔时间小于执行时间时多个线程运行形成的,多个线程没法同时中止;

ZeDVl4.gif

  1. 是一个轻量级的计时器;
  2. 全部的参数所有在构造函数中进行了设置;
  3. 能够设置启动时间;
  4. 不建议再 WinForm 程序中使用。

咱们来看一下代码(在控制台应用程序中输入如下代码):

static System.Threading.Timer threadingTimer;
static int numSum = 0;
static void Main(string[] args)
{
    threadingTimer = new System.Threading.Timer(new System.Threading.TimerCallback(threadingTimer_Elapsed), null, 0, 1000);
    Console.Read();
}
private static void threadingTimer_Elapsed(object state)
{
    for (int i = 0; i < 10000; i++)
    {
        numSum++;
        Console.WriteLine("输出数字:"+i);
    }

    if (numSum > 10000)
    {
        threadingTimer.Dispose();
        Console.WriteLine("结束");
    }
}
注意:当咱们再也不须要多线程Timer计时器的时候,咱们能够调用 Dispose 方法释放所占有的资源。可是由于Timer计时器是按线程池线程来安排回调执行的,所以回调可能发生在 Dispose方法的重载被调用以后,因此咱们可使用可以使用 Dispose(WaitHandle) 方法等待全部回掉完成。
相关文章
相关标签/搜索