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

.NET中的Timer类型用法详解

程序员文章站 2024-02-12 22:03:46
在.net framework中有多个timer,那么怎么根据实际情况进行选择确实是一个问题。 总体而言,计时器共有以下四种: 多线程计时器: 1 system.th...

在.net framework中有多个timer,那么怎么根据实际情况进行选择确实是一个问题。

总体而言,计时器共有以下四种:

多线程计时器:

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或者wpf 中控件的值 这种简单任务来说更方便。 例如时钟和计数显示。否则,你需要一个多线程计时器。

原理:单线程使用消息循环机制,这意味着tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个tick消息。

示例代码如下:

public static void main()
{
system.windows.forms.timer tmr = new system.windows.forms.timer();
tmr.tick += new eventhandler(tmr_tick);
tmr.start();//开始计时器
tmr.stop();//停止计时器
tmr.enabled =true;//设置或获取计时器是否正在运行
tmr.interval = 10000; //计时器的时间间隔 (10秒),以毫秒为单位,在计时器事件tmr_tick开始10秒后进行第一次执行.
}
void tmr_tick(object sender, eventargs e)
{
  //到达指定时间间隔应处理的代码
}

当tmr_tick执行时间较长,ui界面会卡顿,如下图所示:

.NET中的Timer类型用法详解

多线程计时器比较强大,精确,而且可扩展性强;使用多线程计时器时不会对主线程造成任何影响,也就不会出现上面图片显示的情况.

原理:多线程计时器使用回调方法并由线程池线程提供服务.当计时器间隔小于执行此回调(tick方法)所需的时间时,回调可以同时在多个线程中执行,比如当计时器的时间间隔是5秒,但过了5秒后,上一次的回调仍未完成,此时新的回调将在新的线程中运行.在开发中需要避免此种情况。

system.threading.timer是最简单的多线程计时器。
只要在使用 system.threading.timer,就必须保留对它的引用。对于任何托管对象,如果没有对 timer 的引用,计时器会被垃圾回收。即使 timer 仍处在活动状态,也会被回收。
 
在下面的例子中,计时器在5秒后开始定时1秒的调用tick方法。

public static void main()
{
int duetime = 5000;
int period = 1000;
system.threading.timer timer = new system.threading.timer(tick,"给tick方法传的参数,object类型",duetime ,period );
duetime = 10000;
period = 2000;
//修改等待时间为10秒和间隔时间为2秒
timer.change(duetime, period);
//取消计时器
timer.dispose();
}
static void tick(object data)
{
 console.writeline(data);
//如果此时需要访问控件,因为回调线程跟主线程是完全不同的两个线各,因此需要使用control.invoke或begininvoke方法,来实现,例如:
this.begininvoke((methodinvoker)delegate()
{
  this.lbl_w.text = data.tostring ();
 }); 
}

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

1.实现了component,所以可以在设计器显示。
2.用interval属性代替代替change方法
3.添加了elapsed事件, 启动和停止timer的start和stop方法。
4.添加了autoreset属性 默认为true 来指定是否在每次指定的间隔结束时引发elapsed事件,还是仅运行一次elapsed事件就结束

示例代码如下:

public static void mainthread()
{
 system.timers.timer timer tmr=new system.timers.timer();
 tmr.interval=500;
 tmr.elapsed+=newelapsedeventhandler(tmr_elapsed);
 tmr.autoreset = false;
 tmr.start();
 console.readline();
 tmr.stop();
 console.readline();
 tmr.dispose();
}
void tmr_elapsed(objectsender,elapsedeventargse)
{
 console.writeline("tick...");
}

结论:
wpf和windows forms的单线程计时器都非常适合小任务,尤其是界面更新的任务。例如时钟和计数显示。
否则,你只能使用多线程计时器,对于使用哪一种多线程计时器,可根据自己的需要来决定

希望本文所述对大家掌握.net中timer的用法有所帮助。