概述(来自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. 修改placeholder颜色

    #contact_info为textarea的ID #contact_info::-webkit-input-placeholder{ color:#999;}#contact_info:-moz-p ...

  2. [PR & ML 1] [Introduction] Informal Basic Concepts

    最近还没更完OpenCV又开了新坑,谁教machine learning处在紧急又重要的地位呢.更新的内容总结自Pattern Recognition and Machine Learning by ...

  3. bzoj1002:[FJOI2007]轮状病毒

    思路:一道很裸的生成树计数问题,然而要高精度,而且听说直接行列式求值会被卡精度,所以可以模拟行列式求值的过程得到递推公式:f[i]=3*f[i-1]-f[i-2]+2,证明详见vfk博客: http: ...

  4. Build Error 6041: Internal build error

    Note: Following content is reprinted from the Original article Flexera : Build Error 6041. Only for ...

  5. STL容器与配接器

    STL容器包括顺序容器.关联容器.无序关联容器 STL配接器包括容器配接器.函数配接器 顺序容器: vector                             行为类似于数组,但可以根据要求 ...

  6. jquery.animate用法

    <!DOCTYPE html><html><head><script src="http://libs.baidu.com/jquery/1.10. ...

  7. 3d旋转--transform-style: preserve-3d,translate3d(x,y,z),perspective()

    transform-style: preserve-3d,translate3d(x,y,z),perspective() 让其倾斜的核心:加perspective(600px)让其动的核心:rans ...

  8. JavaScript的语法要点 2 - Scope Chain

    前文所述,JavaScript是基于词法作用域(lexically scoped)的,所以标识符被固定在它们被定义的作用域而不是语法上或是其被调用时的作用域.即全局变量的作用域是整个程序,局部变量的作 ...

  9. php 开启缓冲,页面纯静态化

    服务器默认不开启php缓冲区 两种方法开启 1.php.ini out_put_buffer = on 2.ob_start(); 页面纯静态化 file_put_contents()写文件 ob_s ...

  10. Python获取两个ip之间的所有ip

    int_ip = lambda x: '.'.join([str(x/(256**i)%256) for i in range(3,-1,-1)]) ip_int = lambda x:sum([25 ...