C#实现定时器的几种方案
前几天写了一篇java的定时器方案,应小伙伴的要求,今天这里一下c#实现定时器的方案。
在C#里关于定时器类就有三个
1、System.Windows.Forms.Timer
2、System.Threading.Timer
3、定义在System.Timers.Timer
下面对这三个类进行讲解。
System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中 的Timer控件,内部使用API SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环,Console Application(控制台应用程序)无法使用。
System.Timers.Timer和System.Threading.Timer非常类似,它们都是通过.NET Thread Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。System.Timers.Timer还可以应用于WinForm,完全取代上面的System.Windows.Forms.Timer控件。
System.Windows.Forms.Timer
计时器最宜用于 Windows 窗体应用程序中,并且必须在窗口中使用,适用于单线程环境,
在此环境中, UI 线程用于执行处理。 它要求用户代码提供 UI 消息泵, 并且始终从同一线程操作, 或将调用封送到
其他线程。Windows 窗体计时器组件是单线程的, 且限制为55毫秒的准确度,准确性不高
public partial class frmTimerDemo : Form
{
private System.Windows.Forms.Timer timerGetTime;
private void frmTimerDemo_Load(object sender, EventArgs e)
{
//创建定时器
timerGetTime = new System.Windows.Forms.Timer();
//设置定时器属性
timerGetTime.Tick+=new EventHandler(HandleTime);
timerGetTime.Interval = 1000;
timerGetTime.Enabled = true;
//开启定时器
timerGetTime.Start();
}
public void HandleTime(Object myObject, EventArgs myEventArgs)
{
labelTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
private void frmTimerDemo_FormClosed(object sender, FormClosedEventArgs e)
{
//停止定时器
timerGetTime.Stop();
}
}
System.Timers.Timer这个是目前我们定时项目中常用的。
System.Timers.Timer t = new System.Timers.Timer(10000);//实例化Timer类,设置间隔时间为10000毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(Execute);//到达时间的时候执行事件;
t.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
t.Start(); //启动定时器
//上面初始化代码可以写到构造函数中
public void Execute(object source, System.Timers.ElapsedEventArgs e)
{
t.Stop(); //先关闭定时器
MessageBox.Show("OK!");
t.Start(); //执行完毕后再开启器
}
这里需要注意的是Execute方法中一定要先关闭定时器,执行完毕后再开启。这个是本人经过测试的,如果你注释掉这两句,定时器会不断的执行Execute方法,如果Execute执行的是一个很耗时的方法,会导致方法未执行完毕,定时器又启动了一个线程来执行Execute方法。
System.Threading.Timer
线程计时器也不依赖窗体,是一种简单的、轻量级计时器,它使用回调方法而不是使用事件,并由线程池线程提供支持,先看下面代码
class Program
{
int TimesCalled = 0;
void Display(object state)
{
Console.WriteLine("{0} {1} keep running.", (string)state, ++TimesCalled);
}
static void Main(string[] args)
{
Program p = new Program();
//2秒后第一次调用,每1秒调用一次
System.Threading.Timer myTimer = new System.Threading.Timer(p.Display, "Processing timer event", 2000, 1000);
// 第一个参数是:回调方法,表示要定时执行的方法,第二个参数是:回调方法要使用的信息的对象,或者为空引用,第三个参数是:调用 callback 之前延迟的时间量(以毫秒为单位),指定 Timeout.Infinite 以防止计时器开始计时。指定零 (0) 以立即启动计时器。第四个参数是:定时的时间时隔,以毫秒为单位
Console.WriteLine("Timer started.");
Console.ReadLine();
}
}
上面是c#定时器的集中方案,大家在使用中一定要尽量把定时器声明成静态(static),如果放在实例方法中,会导致实例对象被回收导致定时器失效。
如果这篇文章对您有帮助,可转发分享一下。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Go语言出现后,Java还是最佳选择吗?
阿里妹导读:随着大量新生的异步框架和支持协程的语言(如Go)的出现,在很多场景下操作系统的线程调度成为了性能的瓶颈,Java也因此被质疑是否不再适应最新的云场景了。4年前,阿里JVM团队开始自研Wisp2,将Go语言的协程能力带入到Java世界。既享受Java的丰富生态,又获得异步程序的性能,Wisp2让Java平台历久弥新。 Java平台一直以生态的繁荣著称,大量的类库、框架帮助开发者们快速搭建应用。而其中大部分Java框架类库都是基于线程池以及阻塞机制来服务并发的,主要原因包括: Java语言在核心类库中提供了强大的并发能力,多线程应用可以获得不俗的性能; Java EE的一些标准都是线程级阻塞的(比如JDBC); 基于阻塞模式可以快速地开发应用。 但如今,大量新生的异步框架和支持协程的语言(如Go)的出现,在很多场景下操作系统的线程调
-
下一篇
nsq (三) 消息传输的可靠性和持久化[一]
上两篇帖子主要说了一下nsq的拓扑结构,如何进行故障处理和横向扩展,保证了客户端和服务端的长连接,连接保持了,就要传输数据了,nsq如何保证消息被订阅者消费,如何保证消息不丢失,就是今天要阐述的内容。 nsq topic、channel、和消费我客户端的结构如上图,一个topic下有多个channel每个channel可以被多个客户端订阅。消息处理的大概流程:当一个消息被nsq接收后,传给相应的topic,topic把消息传递给所有的channel ,channel根据算法选择一个订阅客户端,把消息发送给客户端进行处理。看上去这个流程是没有问题的,我们来思考几个问题 网络传输的不确定性,比如超时;客户端处理消息时崩溃等,消息如何重传; 如何标识消息被客户端成功处理完毕; 消息的持久化,nsq服务端重新启动时消息不丢失; 服务端对发送中的消息处理逻辑 之前的帖子说过客户端和服务端进行连接后,会启动一个gorouting来发送信息给客户端 go p.messagePump(client, messagePumpStartedChan) 然后会监听客户端发过来的命令client.Reader...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- MySQL数据库在高并发下的优化方案
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能