**** Merged from MCS ****
[mono-project.git] / mcs / class / System / System.Timers / Timer.cs
blob62bfb336b29f1a7051cf080b2faf0cdad0dd03ee
1 //
2 // System.Timers.Timer
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
8 //
9 // The docs talk about server timers and such...
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System;
33 using System.ComponentModel;
34 using System.Threading;
36 namespace System.Timers
38 [DefaultEventAttribute("Elapsed")]
39 [DefaultProperty("Interval")]
40 public class Timer : Component, ISupportInitialize
42 bool autoReset;
43 bool enabled;
44 double interval;
45 ISynchronizeInvoke so;
46 ManualResetEvent wait;
48 [Category("Behavior")]
49 [TimersDescription("Occurs when the Interval has elapsed.")]
50 public event ElapsedEventHandler Elapsed;
52 public Timer () : this (100)
56 public Timer (double interval)
58 autoReset = true;
59 enabled = false;
60 Interval = interval;
61 so = null;
62 wait = null;
66 [Category("Behavior")]
67 [DefaultValue(true)]
68 [TimersDescription("Indicates whether the timer will be restarted when it is enabled.")]
69 public bool AutoReset
71 get { return autoReset; }
72 set { autoReset = value; }
75 [Category("Behavior")]
76 [DefaultValue(false)]
77 [TimersDescription("Indicates whether the timer is enabled to fire events at a defined interval.")]
78 public bool Enabled
80 get { return enabled; }
81 set {
82 if (enabled == value)
83 return;
85 enabled = value;
86 if (value) {
87 Thread t = new Thread (new ThreadStart (StartTimer));
88 t.IsBackground = true;
89 t.Start ();
90 } else {
91 StopTimer ();
96 [Category("Behavior")]
97 [DefaultValue(100)]
98 [RecommendedAsConfigurable(true)]
99 [TimersDescription( "The number of milliseconds between timer events.")]
100 public double Interval
102 get { return interval; }
103 set {
104 // The doc says 'less than 0', but 0 also throws the exception
105 if (value <= 0)
106 throw new ArgumentException ("Invalid value: " + interval, "interval");
108 interval = value;
112 public override ISite Site
114 get { return base.Site; }
115 set { base.Site = value; }
118 [DefaultValue(null)]
119 [TimersDescriptionAttribute("The object used to marshal the event handler calls issued " +
120 "when an interval has elapsed.")]
121 public ISynchronizeInvoke SynchronizingObject
123 get { return so; }
124 set { so = value; }
127 public void BeginInit ()
129 // Nothing to do
132 public void Close ()
134 StopTimer ();
137 public void EndInit ()
139 // Nothing to do
142 public void Start ()
144 Enabled = true;
147 public void Stop ()
149 Enabled = false;
152 protected override void Dispose (bool disposing)
154 Close ();
155 base.Dispose (disposing);
158 static void Callback (object state)
160 Timer timer = (Timer) state;
161 if (timer.Elapsed == null)
162 return;
164 ElapsedEventArgs arg = new ElapsedEventArgs (DateTime.Now);
166 if (timer.so != null && timer.so.InvokeRequired) {
167 timer.so.BeginInvoke (timer.Elapsed, new object [2] {timer, arg});
168 } else {
169 timer.Elapsed (timer, arg);
173 void StartTimer ()
175 wait = new ManualResetEvent (false);
177 WaitCallback wc = new WaitCallback (Callback);
178 while (enabled && wait.WaitOne ((int) interval, false) == false) {
179 if (autoReset == false)
180 enabled = false;
182 ThreadPool.QueueUserWorkItem (wc, this);
185 wc = null;
186 ((IDisposable) wait).Dispose ();
187 wait = null;
190 void StopTimer ()
192 if (wait != null)
193 wait.Set ();