.NET中的Timer类型用法详解
作者:shichen2014 发布时间:2022-12-15 18:33:23
在.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界面会卡顿,如下图所示:
多线程计时器比较强大,精确,而且可扩展性强;使用多线程计时器时不会对主线程造成任何影响,也就不会出现上面图片显示的情况.
原理:多线程计时器使用回调方法并由线程池线程提供服务.当计时器间隔小于执行此回调(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的用法有所帮助。
猜你喜欢
- 最近要实现一个功能,就是checkbox跨页多选,在网上看了一下,资料很少,而且大多是不完全的。不过经过我的努力,终于做出来了。
- 在 javax.validation.constraints包中定义了非常多的校验注解,引入依赖:<dependency> &n
- 下面是一个邮件接收的工具类,有点长!!!public class ReciveMail { private MimeMessage msg
- 本文研究的主要是Java中finally和return的关系,具体介绍和实例如下所示。finally 和 return 关系的总结1.try
- 1.简述描述:1、对输入的字符串进行加解密,并输出。2、加密方法为:当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如
- 创建我们来看看,使用Arrays 怎么创建一个新的数组,一般来说,我们可以使用Arrays 的 copyOf , copyOfRange 和
- 问题:为什么有缓存mybatis默认开启一级缓存什么场景下必须需要关闭一级缓存场景:执行2次相同sql,但是第一次查询sql结果会加工处理,
- springboot跳转到指定页面controller的写法必须是templates下面的页面,不经过配置,无法直接跳转到public,st
- 前言最近有个网友问了我一个问题:系统中大事务问题要如何处理?正好前段时间我在公司处理过这个问题,我们当时由于项目初期时间比较紧张,为了快速完
- 前言aop面向切面编程,是编程中一个很重要的思想本篇文章主要介绍的是SpringBoot切面Aop的使用和案例什么是aopAOP(Aspec
- filter自定义过滤器 增加了 对验证码的校验package com.youxiong.filter;import com.y
- SpringBoot2之PUT请求接收不了参数的解决办法,这个问题,关乎两个Filter过滤器,是spring3和3.5之后提供的,目的就是
- 目录前言实现思路实测前言需求 导出Excel:本身以为是一个简单得导出,但是每行得记录文件中有一列为图片url,需要下载所有记录行对应得图片
- 以下教程是小编在参与开发公司的一个crm系统,整理些相关资料,在该系统中有很多消息推送功能,在其中用到了websocket技术。下面小编整理
- 概述什么是动态编程?动态编程解决什么问题?Java中如何使用?什么原理?如何改进?(需要我们一起探索,由于自己也是比较菜,一般深入不到这个程
- 1、找奇数:public static boolean isOdd(int i){ return i % 2 == 1; }上面的方法真
- 具体代码如下所示:public class Parent { public static int a = parentStati
- 一、读取系统配置文件application.yaml1、application.yaml配置文件中增加一下测试配置testdata: &nb
- 一、案例场景遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样——public static
- 在java 中需要设置三个环境变量(1.5之后不用再设置classpath了,但个人强烈建议继续设置以保证向下兼用问题)JDK安装完成之后我