[C#]System.Timers.Timer(2)
摘要
之前学习过c#中定时器Timer的基本用法,在使用过程中,有一个问题,一直困扰着自己,就是在初始化定时器的时候,如果设置的interval过小,或者每次执行的业务非常耗时的时候,这时候该怎么处理?第一次还没执行结束,下一次已经触发了。
基础
之前学习时的一个例子:http://www.cnblogs.com/wolf-sun/p/5849229.html
一个例子
如果设置的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 = ;
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed += timer_Elapsed;
Console.Read();
}
static int count = ;
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("第{0}次触发", count.ToString());
if (count == )
{
timer.Enabled = false;
}
Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep();
Console.WriteLine("第{0}次处理完成", count.ToString());
count++; }
}
}
执行过程
但实际中由于业务非常复杂,执行很耗时
System.Threading.Thread.Sleep();
可以看到这是,已经开始乱了,线程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 = ;
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed += timer_Elapsed;
Console.Read();
}
static int count = ;
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (obj)
{
Console.WriteLine("第{0}次触发", count.ToString());
if (count == )
{
timer.Enabled = false;
}
Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep();
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 == )
{
timer.Enabled = false;
}
Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep();
Console.WriteLine("第{0}次处理完成", count.ToString());
count++;
isRunning = true;
} }
运行结果
但仍有另外一种方式,可以在当前处理业务的时候,将当前的timer先停止,执行完毕之后开启。
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Enabled = false;
if (count == )
{
timer.Enabled = false;
return;
}
Console.WriteLine("第{0}次触发", count.ToString());
Console.WriteLine("当前线程:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep();
Console.WriteLine("第{0}次处理完成", count.ToString());
timer.Enabled = true;
count++;
}
执行结果
总结
可以尝试测试开启100个定时器甚至更多的进行测试比较,推荐使用处理业务之前关闭,处理结束之后开启的方式。
[C#]System.Timers.Timer(2)的更多相关文章
- C# System.Timers.Timer的一些小问题?
比如设置间隔时间是 1000msSystem.Timers.Timer mytimer = new System.Timers.Timer(1000);问题若响应函数执行的时间超过了 1000 ms, ...
- [C#]System.Timers.Timer
摘要 在.Net中有几种定时器,最喜欢用的是System.Timers命名空间下的定时器,使用起来比较简单,作为定时任务,有Quartz.net,但有时候,一个非常简单的任务,不想引入这个定时任务框架 ...
- C# --System.Timers.Timer 定时方法
注意Start() 注意要等Interval 时间间隔 static void Main(string[] args) { System.Timers.Timer t = new System.Tim ...
- System.Windows.Forms.Timer与System.Timers.Timer的区别(zz)
.NET Framework里面提供了三种Timer: System.Windows.Forms.Timer System.Timers.Timer System.Threading.Timer VS ...
- 使用System.Timers.Timer类实现程序定时执行
使用System.Timers.Timer类实现程序定时执行 在C#里关于定时器类有3个:System.Windows.Forms.Timer类.System.Threading.Timer类和Sys ...
- .NET System.Timers.Timer的原理和使用(开发定时执行程序)
概述(来自MSDN) Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发Elapsed 事件的周期性间隔.然后可以操控此事件以提供定期处理.例如,假设您有一台关键性服务器,必须每周7 ...
- C# 定时器-System.Timers.Timer
using Newtonsoft.Json; using Rafy; using Rafy.Domain; using System; using System.Collections.Generic ...
- .Net Windows Service(服务) 调试安装及System.Timers.Timer 使用
Windows Service(服务) 是运行在后台的进程 1.VS建立 Windows 服务(.NET Framework) 2.添加Timer 双击Service1.cs可以拖控件(System ...
- System.Windows.Forms.Timer、System.Timers.Timer、System.Threading.Timer的 区别和用法
System.Windows.Forms.Timer执行的时候,如果你在过程中间加一个sleep整个的界面就死掉了,但是另外两个没有这个情况,System.Timers.Timer.System.Th ...
- C# 定时执行方法: System.Timers.Timer用法示例
System.Timers.Timer t = new System.Timers.Timer(5000); //设置时间间隔为5秒 private void Form1_Load(ob ...
随机推荐
- Fiddler工具使用介绍三
我们知道Fiddler是位于客户端和服务器之间的代理,它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据.设置断点.调试web应用.修改请求的数据,甚至可以修改 ...
- 文本属性和字体属性,超链接导航栏案例 background
文本属性 介绍几个常用的. 文本对齐 text-align 属性规定元素中的文本的水平对齐方式. 属性值:none | center | left | right | justify 文本颜色 col ...
- GoLang学习控制语句之switch
基本结构 相比较 C 和 Java 等其它语言而言,Go 语言中的 switch 结构使用上更加灵活.它接受任意形式的表达式,例如: switch var1 { case val1: ... case ...
- Tomcat 启动成功后报 INFO [Timer-0] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access:
Tomcat 启动成功后报 INFO [Timer-0] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceL ...
- input输入框添加内部图标
有可能在制作网页的过程中遇到各种美化表单设计,这次我们来试着做一个demo 将input输入框添加内部图标 话不多说,看一下最终效果 我们的思路是,在一个div中,加入一个div和一个input标签, ...
- postgresql-死锁
死锁问题:1.长事务,事务中包含了文书的上传下载,导致其他表的锁等待,最终导致死锁. 2.并发更新,如果更新慢的话,很可能导致,锁等待.需要加for update或者ad lock 3.数据库中查询p ...
- ProxySQL 部署 Single Writer Failover 读写分离 (PXC)
主机信息: Proxysql: 如果你忽略了ProxySQL会报告主机组的变化,我建议把它设置为0,除非你试图调试"某些东西",否则你的日志将很快变得巨大.UPDATE globa ...
- vue-cli2 构建速度优化
对于使用 vue-cli 脚手架创建的前端项目,编译发布几乎是必需操作,有的编译只需要几秒钟,快如闪电,有的却需要好几分钟,慢如蜗牛.如果是线上进行热修复,那更是分秒必争,网页响应的速度直接影响了用户 ...
- oracle RAC srvctl命令关闭节点实例的时候 不能正常执行
场景描述: [oracle@oracle01 admin]$ srvctl stop database -d oradb1 PRCD- : The resource for database ORAD ...
- C语言编码转换gb2312 to utf8,utf8 to gb2312 代码,GCC编译,支持Windows、Linux
编译:gcc -o f.exe f.c -liconv #include <stdio.h> #include <stdlib.h> #include <stddef.h ...