[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 ...
随机推荐
- nginx 常见错误释义
错误信息 错误说明 "upstream prematurely(过早的) closed connection" 请求uri的时候出现的异常,是由于upstream还未返回应答给用户 ...
- .NET 证书加密 存储保存 IIS授权
最近接到一个任务,加密DotNet项目的配置文件.配置文件里需要加密的地方一共有两块,一个是数据库连接字符串,一个是自定义的所有AppSettings. 一开始接到这个任务我是拒绝的,因为压根不知道怎 ...
- 如何将Skyline66嵌入WPF中
1.新建WPF项目: 2.添加引用 .net引用:System.Windows.Forms和WindowsFormsIntegration skyline引用:AxInterop.TerraExplo ...
- 迁移桌面程序到MS Store(3)——开机自启动
迁移桌面程序的时候,有可能你会遇到这么个需求——开机自启动.Windows传统桌面程序的传统陋习.不论什么奇葩软件都想要开机自启动,默认就给你打开,一开机哐哐哐什么雷,什么企鹅都蹦出来,也不管你用不用 ...
- 【转】OAuth的改变
原文地址:http://huoding.com/2011/11/08/126 去年我写过一篇<OAuth那些事儿>,对OAuth做了一些简单扼要的介绍,今天我打算写一些细节,以阐明OAut ...
- Java零基础教程(二)基础语法
Java 基础语法 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如 ...
- D16——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D16 20180927内容纲要: 1.JavaScript介绍 2.JavaScript功能介绍 3.JavaScript变量 4.Dom操作 a.获取标签 b ...
- [LeetCode]最长回文子串 java
题目: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: ...
- 几种int类型的范围
我们在编程的过程经常会遇到数据溢出的情况,于是这个时候我们必须定义能表示更大的数的数据类型来表示这个数. 下面列出了int型的范围: unsigned int 0-4294967295 ...
- NPM(Node Package Manager,Node包管理器)
简介 每个Node应用都有一个包含该应用元数据的文件-package.json,包含应用名.版本号以及依赖等信息. 我们使用NPM从NPM库下载并安装第三方包. 所有下载的包以及其依赖都保存在node ...