博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C#]System.Timers.Timer(2)
阅读量:6957 次
发布时间:2019-06-27

本文共 3671 字,大约阅读时间需要 12 分钟。

摘要

之前学习过c#中定时器Timer的基本用法,在使用过程中,有一个问题,一直困扰着自己,就是在初始化定时器的时候,如果设置的interval过小,或者每次执行的业务非常耗时的时候,这时候该怎么处理?第一次还没执行结束,下一次已经触发了。

基础

之前学习时的一个例子:

一个例子

如果设置的interval比较大,而业务执行过程耗时很小,如下所示:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Timers;namespace TimerTest{    class Program    {        static Timer timer = new Timer();        static void Main(string[] args)        {            timer.Interval = 1000;            timer.AutoReset = true;            timer.Enabled = true;            timer.Elapsed += timer_Elapsed;            Console.Read();        }        static int count = 1;        static void timer_Elapsed(object sender, ElapsedEventArgs e)        {            Console.WriteLine("第{0}次触发", count.ToString());            if (count == 10)            {                timer.Enabled = false;            }            Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);            System.Threading.Thread.Sleep(10);            Console.WriteLine("第{0}次处理完成", count.ToString());            count++;        }    }}

执行过程

但实际中由于业务非常复杂,执行很耗时

System.Threading.Thread.Sleep(2000);

可以看到这是,已经开始乱了,线程id已经变了,如果在里面涉及到引用的类型,必然引起多个线程修改同一个变量的问题,造成并不是我们想要的结果。

当然,这个时候有很多处理方法,加锁,或者设置标致量,等本次运行结束时,再运行下一次的。但这种方式,会造成timer的空转。

加锁

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Timers;namespace TimerTest{    class Program    {        static readonly object obj = new object();        static Timer timer = new Timer();        static void Main(string[] args)        {            timer.Interval = 1000;            timer.AutoReset = true;            timer.Enabled = true;            timer.Elapsed += timer_Elapsed;            Console.Read();        }        static int count = 1;        static void timer_Elapsed(object sender, ElapsedEventArgs e)        {            lock (obj)            {                Console.WriteLine("第{0}次触发", count.ToString());                if (count == 10)                {                    timer.Enabled = false;                }                Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);                System.Threading.Thread.Sleep(2000);                Console.WriteLine("第{0}次处理完成", count.ToString());                count++;            }                    }    }}

执行

标志量

static void timer_Elapsed(object sender, ElapsedEventArgs e)        {            if (isRunning)            {                isRunning = false;                Console.WriteLine("第{0}次触发", count.ToString());                if (count == 10)                {                    timer.Enabled = false;                }                Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);                System.Threading.Thread.Sleep(2000);                Console.WriteLine("第{0}次处理完成", count.ToString());                count++;                isRunning = true;            }        }

运行结果

但仍有另外一种方式,可以在当前处理业务的时候,将当前的timer先停止,执行完毕之后开启。

static void timer_Elapsed(object sender, ElapsedEventArgs e)        {            timer.Enabled = false;                      if (count == 10)            {                timer.Enabled = false;                return;            }            Console.WriteLine("第{0}次触发", count.ToString());            Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);            System.Threading.Thread.Sleep(2000);            Console.WriteLine("第{0}次处理完成", count.ToString());            timer.Enabled = true;            count++;        }

执行结果

总结

可以尝试测试开启100个定时器甚至更多的进行测试比较,推荐使用处理业务之前关闭,处理结束之后开启的方式。

转载于:https://www.cnblogs.com/wolf-sun/p/6635180.html

你可能感兴趣的文章
另类文件加密 图片当密码给文本加密
查看>>
MySQL数据库如何解决大数据量存储问题
查看>>
CENTOS6.5 yum配置
查看>>
《自顶向下网络设计(第3版)》——1.6 复习题
查看>>
【转】微信小程序给程序员带来的可能是一个赚钱的机遇
查看>>
《Programming Ruby中文版:第2版》终于正式出版了
查看>>
使用Observium来监控你的网络和服务器
查看>>
蚂蚁区块链团队资讯简报20170514
查看>>
线性空间(向量空间)
查看>>
多媒体之录音
查看>>
mysql 分区类型详解
查看>>
ORACLE同义词总结
查看>>
ios字体设置
查看>>
【SICP练习】51 练习2.19
查看>>
solveCrossprod求 X'X的逆, ( X' == t(X), 即X的行列变换矩阵 )
查看>>
PostgreSQL column cryptographic use pgcrypto extension and optional openssl lib
查看>>
通过支付宝服务中断事件看系统可靠性和YunOS的可靠性
查看>>
oVirt VM (CentOS) template & clone
查看>>
Flutter框架分析(二)-- 初始化
查看>>
mac更新系统后Android studio Git不能用,提示missing xcrun at
查看>>