概述(来自MSDN)

Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发Elapsed 事件的周期性间隔。然后可以操控此事件以提供定期处理。例如,假设您有一台关键性服务器,必须每周7 天、每天24 小时都保持运行。可以创建一个使用Timer 的服务,以定期检查服务器并确保系统开启并在运行。如果系统不响应,则该服务可以尝试重新启动服务器或通知管理员。

基于服务器的Timer 是为在多线程环境中用于辅助线程而设计的。服务器计时器可以在线程间移动来处理引发的Elapsed 事件,这样就可以比Windows 计时器更精确地按时引发事件。

基于Interval 属性的值,Timer 组件引发Elapsed 事件。可以处理该事件以执行所需的处理。例如,假设您有一个联机销售应用程序,它不断向数据库发送销售订单。编译发货指令的服务分批处理订单,而不是分别处理每个订单。可以使用Timer 每30 分钟启动一次批处理。

注意

当AutoReset设置为false时,Timer只在第一个Interval过后引发一次Elapsed事件。若要保持以Interval时间间隔引发Elapsed 事件,请将AutoReset设置为true。

Elapsed事件在ThreadPool线程上引发。如果Elapsed事件的处理时间比Interval长,在另一个hreadPool线程上将会再次引发此事件。因此,事件处理程序应当是可重入的。

注意

在一个线程调用Stop 方法或将Enabled 属性设置为false 的同时,可在另一个线程上运行事件处理方法。这可能导致在计时器停止之后引发Elapsed 事件。Stop 方法的示例代码演示了一种避免此争用条件的方法。

如果和用户界面元素(如窗体或控件)一起使用Timer,请将包含有Timer 的窗体或控件赋值给SynchronizingObject 属性,以便将此事件封送到用户界面线程中。Timer 在运行时是不可见的。

几点说明

1 private System.Timers.Timer _TestTimerEvent= new Timer();

1

1、默认的周期是0.1秒执行一次;

2、AutoReset的初始值为true.

3、它的timer机制和System.Threading.Timer 原理是一样的。

4、每次周期(Timer)运行一次会新起一个线程。

5、如果Elapsed事件的处理时间比Interval长,它每个周期执行都会新起一个线程,这个线程的执行时间不受interval的限定,可以比interval长,因为一个新周期执行,又会新起一个线程,Timer起的线程周期就是事件处理时间。

我们来看它的实现代码.(.net framework 提供的).

001 //------------------------------------------------------------------------------

002 // <copyright file="Timer.cs" company="Microsoft">

003 //     Copyright (c) Microsoft Corporation.  All rights reserved.

004 // </copyright>

005 //-----------------------------------------------------------------------------

006

007 namespace System.Timers {

008

009     using System.Runtime.InteropServices;

010     using System.Security;

011     using System.Security.Permissions;

012     using System.Threading;

013     using System.ComponentModel;

014     using System.ComponentModel.Design;

015     using System;

016     using Microsoft.Win32;

017     using Microsoft.Win32.SafeHandles;

018

019     /// <devdoc>

020     ///    <para>Handles recurring events in an application.</para>

021     /// </devdoc>

022     [

023     DefaultProperty("Interval"),

024     DefaultEvent("Elapsed"),

025     HostProtection(Synchronization=true, ExternalThreading=true)

026     ]

027     public class Timer : Component, ISupportInitialize {

028         private double interval;

029         private bool  enabled;

030         private bool initializing;

031         private bool delayedEnable;

032         private ElapsedEventHandler onIntervalElapsed;

033         private bool autoReset;

034         private ISynchronizeInvoke synchronizingObject;

035         private bool disposed;

036         private System.Threading.Timer timer;

037         private TimerCallback callback;

038         private Object cookie;

039

040         /// <devdoc>

041         /// <para>Initializes a new instance of the <see cref='System.Timers.Timer'/> class, with the properties

042         ///    set to initial values.</para>

043         /// </devdoc>

044         public Timer()

045         : base() {

046             interval = 100;

047             enabled = false;

048             autoReset = true;

049             initializing = false;

050             delayedEnable = false;

051             callback = new TimerCallback(this.MyTimerCallback);

052         }

053

054         /// <devdoc>

055         ///    <para>

056         ///       Initializes a new instance of the <see cref='System.Timers.Timer'/> class, setting the <see cref='System.Timers.Timer.Interval'/> property to the specified period.

057         ///    </para>

058         /// </devdoc>

059         public Timer(double interval)

060         : this() {

061             if (interval <= 0)

062                 throw new ArgumentException(SR.GetString(SR.InvalidParameter, "interval", interval));

063

064             int i = (int)Math.Ceiling(interval);

065             if( i < 0) {

066                 throw new ArgumentException(SR.GetString(SR.InvalidParameter, "interval", interval));

067             }

068

069             this.interval = interval;

070         }

071

072         /// <devdoc>

073         /// <para>Gets or sets a value indicating whether the Timer raises the Tick event each time the specified

074         /// Interval has elapsed,

075         ///    when Enabled is set to true.</para>

076         /// </devdoc>

077         [Category("Behavior"),  TimersDescription(SR.TimerAutoReset), DefaultValue(true)]

078         public bool AutoReset {

079             get {

080                 return this.autoReset;

081             }

082

083             set {

084                 if (DesignMode)

085                      this.autoReset = value;

086                 else if (this.autoReset != value) {

087                      this.autoReset = value;

088                     if( timer != null) {

089                          UpdateTimer();

090                     }

091                 }

092             }

093         }

094

095         /// <devdoc>

096         /// <para>Gets or sets a value indicating whether the <see cref='System.Timers.Timer'/>

097         /// is able

098         /// to raise events at a defined interval.</para>

099         /// </devdoc>

100         //[....] - The default value by design is false, don't change it.

101         [Category("Behavior"), TimersDescription(SR.TimerEnabled), DefaultValue(false)]

102         public bool Enabled {

103             get {

104                 return this.enabled;

105             }

106

107             set {

108                 if (DesignMode) {

109                     this.delayedEnable = value;

110                     this.enabled = value;

111                 }

112                 else if (initializing)

113                     this.delayedEnable = value;

114                 else if (enabled != value) {

115                     if (!value) {

116                         if( timer != null) {

117                             cookie = null;

118                             timer.Dispose();

119                             timer = null;

120                         }

121                         enabled = value;

122                     }

123                     else {

124                         enabled = value;

125                         if( timer == null) {

126                             if (disposed) {

127                                 throw new ObjectDisposedException(GetType().Name);

128                             }

129

130                             int i = (int)Math.Ceiling(interval);

131                             cookie = new Object();

132                             timer = new System.Threading.Timer(callback, cookie, i, autoReset? i:Timeout.Infinite);

133                         }

134                         else {

135                             UpdateTimer();

136                         }

137                     }

138

139                 }

140           }

141         }

142

143

144         private void UpdateTimer() {

145             int i = (int)Math.Ceiling(interval);

146             timer.Change(i, autoReset? i :Timeout.Infinite );

147         }

148

149         /// <devdoc>

150         ///    <para>Gets or

151         ///       sets the interval on which

152         ///       to raise events.</para>

153         /// </devdoc>

154         [Category("Behavior"), TimersDescription(SR.TimerInterval), DefaultValue(100d), RecommendedAsConfigurable(true)]

155         public double Interval {

156             get {

157                 return this.interval;

158             }

159

160             set {

161                 if (value <= 0)

162                     throw new ArgumentException(SR.GetString(SR.TimerInvalidInterval, value, 0));

163

164                 interval = value;

165                 if (timer != null) {

166                     UpdateTimer();

167                 }

168             }

169         }

170

171

172         /// <devdoc>

173         /// <para>Occurs when the <see cref='System.Timers.Timer.Interval'/> has

174         ///    elapsed.</para>

175         /// </devdoc>

176         [Category("Behavior"), TimersDescription(SR.TimerIntervalElapsed)]

177         public event ElapsedEventHandler Elapsed {

178             add {

179                 onIntervalElapsed += value;

180             }

181             remove {

182                 onIntervalElapsed -= value;

183             }

184         }

185

186         /// <devdoc>

187         ///    <para>

188         ///       Sets the enable property in design mode to true by default.

189         ///    </para>

190         /// </devdoc>

191         /// <internalonly/>

192         public override ISite Site {

193             set {

194                 base.Site = value;

195                 if (this.DesignMode)

196                     this.enabled= true;

197             }

198

199             get {

200                 return base.Site;

201             }

202         }

203

204

205         /// <devdoc>

206         ///    <para>Gets or sets the object used to marshal event-handler calls that are issued when

207         ///       an interval has elapsed.</para>

208         /// </devdoc>

209         [

210         Browsable(false),

211         DefaultValue(null),

212         TimersDescription(SR.TimerSynchronizingObject)

213         ]

214         public ISynchronizeInvoke SynchronizingObject {

215             get {

216                 if (this.synchronizingObject == null && DesignMode) {

217                     IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));

218                     if (host != null) {

219                         object baseComponent = host.RootComponent;

220                         if (baseComponent != null && baseComponent is ISynchronizeInvoke)

221                             this.synchronizingObject = (ISynchronizeInvoke)baseComponent;

222                     }

223                 }

224

225                 return this.synchronizingObject;

226             }

227

228             set {

229                 this.synchronizingObject = value;

230             }

231         }

232

233         /// <devdoc>

234         ///    <para>

235         ///       Notifies

236         ///       the object that initialization is beginning and tells it to stand by.

237         ///    </para>

238         /// </devdoc>

239         public void BeginInit() {

240             this.Close();

241             this.initializing = true;

242         }

243

244         /// <devdoc>

245         ///    <para>Disposes of the resources (other than memory) used by

246         ///       the <see cref='System.Timers.Timer'/>.</para>

247         /// </devdoc>

248         public void Close() {

249             initializing = false;

250             delayedEnable = false;

251             enabled = false;

252

253             if (timer != null ) {

254                 timer.Dispose();

255                 timer = null;

256             }

257         }

258

259         /// <internalonly/>

260         /// <devdoc>

261         /// </devdoc>

262         protected override void Dispose(bool disposing) {

263             Close();

264             this.disposed = true;

265             base.Dispose(disposing);

266         }

267

268         /// <devdoc>

269         ///    <para>

270         ///       Notifies the object that initialization is complete.

271         ///    </para>

272         /// </devdoc>

273         public void EndInit() {

274             this.initializing = false;

275             this.Enabled = this.delayedEnable;

276         }

277

278         /// <devdoc>

279         /// <para>Starts the timing by setting <see cref='System.Timers.Timer.Enabled'/> to <see langword='true'/>.</para>

280         /// </devdoc>

281         public void Start() {

282             Enabled = true;

283         }

284

285         /// <devdoc>

286         ///    <para>

287         ///       Stops the timing by setting <see cref='System.Timers.Timer.Enabled'/> to <see langword='false'/>.

288         ///    </para>

289         /// </devdoc>

290         public void Stop() {

291             Enabled = false;

292         }

293

294         private void MyTimerCallback(object state) {

295             // System.Threading.Timer will not cancel the work item queued before the timer is stopped.

296             // We don't want to handle the callback after a timer is stopped.

297             if( state != cookie) {

298                 return;

299             }

300

301             if (!this.autoReset) {

302                 enabled = false;

303             }

304

305             FILE_TIME filetime = new FILE_TIME();

306             GetSystemTimeAsFileTime(ref filetime);

307             ElapsedEventArgs elapsedEventArgs = new ElapsedEventArgs(filetime.ftTimeLow, filetime.ftTimeHigh);

308             try {

309                 // To avoid ---- between remove handler and raising the event

310                 ElapsedEventHandler intervalElapsed = this.onIntervalElapsed;

311                 if (intervalElapsed != null) {

312                     if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired)

313                         this.SynchronizingObject.BeginInvoke(intervalElapsed, new object[]{this, elapsedEventArgs});

314                     else

315                        intervalElapsed(this,  elapsedEventArgs);

316                 }

317             }

318             catch {

319             }

320         }

321

322         [StructLayout(LayoutKind.Sequential)]

323         internal struct FILE_TIME {

324             internal int ftTimeLow;

325             internal int ftTimeHigh;

326         }

327

328         [DllImport(ExternDll.Kernel32), SuppressUnmanagedCodeSecurityAttribute()]

329         internal static extern void GetSystemTimeAsFileTime(ref FILE_TIME lpSystemTimeAsFileTime);

330     }

331 }

332

333

334 // File provided for Reference Use Only by Microsoft Corporation (c) 2007.

在初始化的时候它的代码实现是这样的.

1 public Timer()

2 : base() {

3     interval = 100;

4     enabled = false;

5     autoReset = true;

6     initializing = false;

7     delayedEnable = false;

8     callback = new TimerCallback(this.MyTimerCallback);

9 }

而如果你是这样的话

01 public Timer(double interval)

02        : this() {

03            if (interval <= 0)

04                throw new ArgumentException(SR.GetString(SR.InvalidParameter, "interval", interval));

05

06            int i = (int)Math.Ceiling(interval);

07            if( i < 0) {

08                throw new ArgumentException(SR.GetString(SR.InvalidParameter, "interval", interval));

09            }

10

11            this.interval = interval;

12        }

你就需要再设置下AutoReset = True;

我们加载事件的Elapsed的代码实现是这样的.

01 /// <devdoc>

02 /// <para>Occurs when the <see cref='System.Timers.Timer.Interval'/> has

03 ///    elapsed.</para>

04 /// </devdoc>

05 [Category("Behavior"), TimersDescription(SR.TimerIntervalElapsed)]

06 public event ElapsedEventHandler Elapsed {

07     add {

08         onIntervalElapsed += value;

09     }

10     remove {

11         onIntervalElapsed -= value;

12     }

13 }

对它的基本原理有一定了解后,我们开始写一个简单的实现程序。

01 using System;

02 using System.Collections.Generic;

03 using System.Linq;

04 using System.Text;

05 using System.Threading;

06 using Timer = System.Timers.Timer;

07 using System.Timers;

08

09 namespace TestMultipleThread

10 {

11

12     public class ThreadWork

13     {

14         private System.Timers.Timer _TestTimerEvent;

15

16         public void StartWork()

17         {

18             _TestTimerEvent = new Timer();

19             _TestTimerEvent.Elapsed += Sum;

20             _TestTimerEvent.Start();

21         }

22

23         public static object lockobject = new object();

24

25

26         private void Sum(object sender, ElapsedEventArgs e)

27         {

28             Console.WriteLine(string.Format("this is thread ID {0}  execute", Thread.CurrentThread.ManagedThreadId));

29             for (int i = 0; i < 10000; i++)

30             {

31                 Thread.Sleep(10);

32             }

33         }

34     }

35

36     class Program

37     {

38         public static void Main()

39         {

40             ThreadWork threadWork = new ThreadWork();

41             ThreadStart myThreadDelegate = new ThreadStart(threadWork.StartWork);

42             Thread myThread = new Thread(myThreadDelegate);

43             myThread.Start();

44

45             Thread.Sleep(1000000);

46         }

47     }

48 }

查看的运行结果是:

我们看下执行的线程数有多少

能说明的一个问题就是在timer每次执行时都会新起一个线程来执行。

.NET System.Timers.Timer的原理和使用(开发定时执行程序)的更多相关文章

  1. System.Timers.Timer

    前言 System.Timers.Timer组件是基于服务器的计时器,它能够指定在应用程序中引发Elapsed事件周期性间隔,以处理相应事件. 使用示例: 运行结果展示: System.Timers. ...

  2. C# System.Timers.Timer的一些小问题?

    比如设置间隔时间是 1000msSystem.Timers.Timer mytimer = new System.Timers.Timer(1000);问题若响应函数执行的时间超过了 1000 ms, ...

  3. [C#]System.Timers.Timer

    摘要 在.Net中有几种定时器,最喜欢用的是System.Timers命名空间下的定时器,使用起来比较简单,作为定时任务,有Quartz.net,但有时候,一个非常简单的任务,不想引入这个定时任务框架 ...

  4. C# --System.Timers.Timer 定时方法

    注意Start() 注意要等Interval 时间间隔 static void Main(string[] args) { System.Timers.Timer t = new System.Tim ...

  5. System.Windows.Forms.Timer与System.Timers.Timer的区别(zz)

    .NET Framework里面提供了三种Timer: System.Windows.Forms.Timer System.Timers.Timer System.Threading.Timer VS ...

  6. 使用System.Timers.Timer类实现程序定时执行

    使用System.Timers.Timer类实现程序定时执行 在C#里关于定时器类有3个:System.Windows.Forms.Timer类.System.Threading.Timer类和Sys ...

  7. C# 定时器-System.Timers.Timer

    using Newtonsoft.Json; using Rafy; using Rafy.Domain; using System; using System.Collections.Generic ...

  8. .Net Windows Service(服务) 调试安装及System.Timers.Timer 使用

    Windows Service(服务)  是运行在后台的进程 1.VS建立 Windows 服务(.NET Framework) 2.添加Timer 双击Service1.cs可以拖控件(System ...

  9. System.Windows.Forms.Timer、System.Timers.Timer、System.Threading.Timer的 区别和用法

    System.Windows.Forms.Timer执行的时候,如果你在过程中间加一个sleep整个的界面就死掉了,但是另外两个没有这个情况,System.Timers.Timer.System.Th ...

随机推荐

  1. ESP8266开发课堂之 - 建立一个新项目

    项目架构 ESP8266项目开发并非使用IDE自动管理工程文件,而是使用了诸多第三方程序如Python,以及使用了Makefile管理依赖与控制编译,所以项目的创建与日常维护较为复杂,本篇将详述创建一 ...

  2. DataList和Repeater

    DataList和Repeater是两个十分有用的控件,在新闻列表和图片展示的地方经常用到.在这里简单的把他们介绍一下. 1.DataList: 前端页面: <asp:DataList ID=& ...

  3. js搜索框 js仿百度搜索 js下拉框 jQuery.Autocomplete使用

    做了一个网站,需要根据文本框的输入模糊搜索数据库内容给出提示供用户选择,就找到了jQuery.Autocomplete 效果如下图: 该插件托管在github上,具体地址:https://github ...

  4. mysql---union和左连接的两倒面试题

    第一道: 思路:无非是将hid与gid与t表中的tname关联起来.实质上是三表关联(m,t,t) 先将hid与tname关联起来,运用左连接 再将结果集与t表中的tname关联起来,使得gid与tn ...

  5. 三个PHP常用代码样例

    作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的.尽管PHP经常被人诟病,被人贬低,被人当玩笑开,事实证明,PHP是全世 ...

  6. Super Hide IP 3.4.7.8允许您以匿名方式进行网上冲浪、 保持隐藏您的 IP 地址

    Super Hide IP 3.4.7.8 转自:http://www.0daydown.com/04/695.html Super Hide IP允许您以匿名方式进行网上冲浪. 保持隐藏您的 IP ...

  7. android实现视频图片取缩略图

    取缩略图不等同于缩放图片. 缩放图片是保持不失真的情况下缩放处理,并进行平滑处理. 缩略图则不然,允许失真,目的只是取出图片的轮廓. 保存Bitmap图片 private void saveBitma ...

  8. 编写jQuery插件--实现返回顶部插件

    国庆过去一周多了,作为IT界的具有严重’工作狂‘性质的宅人,居然还没走出玩耍的心情,拖了程序猿的脚后跟了.最近工作不顺,心情不佳,想吐槽下公司,想了还是厚道点,以彼之道还施彼身,觉得自己也和他们同流合 ...

  9. Codeforces Round #334 (Div. 1) C. Lieges of Legendre

    Lieges of Legendre 题意:有n堆牛,每堆有ai头牛.两个人玩一个游戏,游戏规则为: <1>从任意一个非空的堆中移走一头牛: <2>将偶数堆2*x变成k堆,每堆 ...

  10. org.springframework.orm.jpa.JpaTransactionManager

    [第九章] Spring的事务 之 9.2 事务管理器 ——跟我学spring3 http://sishuok@com/forum/blogPost/list/0/2503.html