欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c#各种Timer类的区别与用法介绍

程序员文章站 2024-02-13 09:22:04
system.threading.timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务。在必须更新用户界面的情况下,建议不要使用该计时器,因为它的回调不...

system.threading.timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务。在必须更新用户界面的情况下,建议不要使用该计时器,因为它的回调不在用户界面线程上发生。在此类情况下,system.windows.threading.dispatchertimer 是更好的选择,因为其事件是在用户界面线程上引发的。
多线程计时器
1:system.threading.timer
2:system.timers.timer

特殊目的的单线程计时器:
1:system.windows.forms.timer(windows forms timer)
2:system.windows.threading.dispatchertimer(wpf timer);

多线程计时器比较强大,精确,而且可扩展性强;
单线程计时器比较安全,对于更新 windows forms controls或者wpf这种简单任务来说更方便。

复制代码 代码如下:

system.threading.timer是最简单的多线程计时器。在下面的例子中,定时器在5秒后开始定时1秒的调用tick方法。
publicstaticvoidmain()
{
//5秒后开始运行,接着每隔1秒的调用tick方法
timertmr=newtimer(tick,"tick...",5000,1000);
console.readline();
tmr.dispose();
}
staticvoidtick(objectdata)
{
console.writeline(data);
}

.net framework提供的另一个计时器system.timers.timer.简单的对system.threading.timer进行了包装。增加了下面几个特性。

实现了component,所以可以在设计器显示。代替change方法的一个interval属性代替callback委托的一个elapsed事件启动和停止timer的enabled属性,默认是false。为了避免enabled造成混乱,提供了start和stop方法。是否在每次指定的间隔结束时引发elapsed时间,还是仅间隔第一次结束后运行的autoreset属性。在wpf或windows forms中安全的调用方法的synchronizingobject对象。publicstaticvoidmainthread()

复制代码 代码如下:

{
timertmr=newtimer();
tmr.interval=500;
tmr.elapsed+=newelapsedeventhandler(tmr_elapsed);
tmr.start();
console.readline();
tmr.stop();
console.readline();
tmr.start();
console.readline();
tmr.dispose();
}

staticvoidtmr_elapsed(objectsender,elapsedeventargse)
{
console.writeline("tick...");
}


单线程计时器:
1:system.windows.forms.timer(windows forms timer)
2:system.windows.threading.dispatchertimer(wpf timer);

单线程计时器是被设计成属于他们执行环境的计时器,如果你在一个windows服务应用程序中使用windows forms的timer,timer 事件并不会被触发,只有在对应的环境下才会被触发。

像system.timers.timer一样,他们也提供了相同的成员(interval,tick,start,stop),但是他们内部的工作原理不同,
wpf和windows forms的计时器使用消息循环机制来取代线程池产生消息的机制。
这意味着tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个tick消息。

下面是它们的优点:
你可以忘记线程安全。一个tick事件在前一个tick事件被处理完毕前不会被触发。你可以直接在tick事件处理代码中更新控件,不需要调用control.invoke或dispatcher.invoke.
看下在winform中使用单线程定时器的效果:

复制代码 代码如下:

//基于windows消息循环的单线程计时器
privatesystem.windows.forms.timertimer=newtimer(){};

publicform1()
{
initializecomponent();

timer.tick+=neweventhandler(timer_tick);
timer.enabled=true;
}

voidtimer_tick(objectsender,eventargse)
{
//模拟的做一些耗时的操作
system.threading.thread.sleep(2000);
}


如果运行上面的代码,会发现ui界面响应速度很慢,
原理上面已经介绍了:单线程计时器基于windows消息循环,应用程序会同步的处理计时器的消息。
解决这个问题的方法是使用多线程计时器:只要修改代码使用多线程计时器即可:
复制代码 代码如下:

//使用多线程计时器
privatesystem.timers.timertimer=newsystem.timers.timer();

publicform1()
{
initializecomponent();

timer.elapsed+=newsystem.timers.elapsedeventhandler(timer_elapsed);
timer.enabled=true;
}

voidtimer_elapsed(objectsender,system.timers.elapsedeventargse)
{
//模拟的做一些耗时的操作
system.threading.thread.sleep(2000);
}


上面的例子告诉我们单线程计时器的缺点:
除非tick事件的处理代码执行的非常快,否则ui界面会变得响应很慢。
所以 wpf和windows forms的计时器都非常适合小任务,尤其是界面更新的任务。例如时钟和计数显示。否则,你需要一个多线程计时器。
设为1000,再设一个变量每次加1.加12次后做你要做的事,这样就准了.

上面是2种自己使用一下,感觉那个好就可以了。