积极答复者
一个timer是否可以看作一个thread?

问题
答案
-
一个Timer可以看成是一个Thread,可以理解成一个死循环的Thread(触发事件的死循环Thread),除非你禁用Timer。
一个Timer里运行Thread,因为Timer本身每隔一定时间(单位:毫秒)会自动触发Tick事件,因此小心产生多个实例。
以上说的是WinForm开发中那个System.Windows.Forms中的Timer。另外还有System.Threading.Timer和System.Timers.Timer.
源代码(Sytem.Windows.Forms.Timer):
[DefaultEvent("Tick"), SRDescription("DescriptionTimer"), DefaultProperty("Interval"), ToolboxItemFilter("System.Windows.Forms")] public class Timer : Component { // Fields private bool enabled; private int interval; private object syncObj; private GCHandle timerRoot; private TimerNativeWindow timerWindow; private object userData; // Events [SRDescription("TimerTimerDescr"), SRCategory("CatBehavior")] public event EventHandler Tick; // Methods public Timer() { this.syncObj = new object(); this.interval = 100; } public Timer(IContainer container) : this() { container.Add(this); } protected override void Dispose(bool disposing) { if (disposing) { if (this.timerWindow != null) { this.timerWindow.StopTimer(); } this.Enabled = false; } this.timerWindow = null; base.Dispose(disposing); } protected virtual void OnTick(EventArgs e) { if (this.onTimer != null) { this.onTimer(this, e); } } public void Start() { this.Enabled = true; } public void Stop() { this.Enabled = false; } public override string ToString() { return (base.ToString() + ", Interval: " + this.Interval.ToString(CultureInfo.CurrentCulture)); } // Properties [DefaultValue(false), SRCategory("CatBehavior"), SRDescription("TimerEnabledDescr")] public virtual bool Enabled { get { if (this.timerWindow == null) { return this.enabled; } return this.timerWindow.IsTimerRunning; } set { lock (this.syncObj) { if (this.enabled != value) { this.enabled = value; if (!base.DesignMode) { if (value) { if (this.timerWindow == null) { this.timerWindow = new TimerNativeWindow(this); } this.timerRoot = GCHandle.Alloc(this); this.timerWindow.StartTimer(this.interval); } else { if (this.timerWindow != null) { this.timerWindow.StopTimer(); } if (this.timerRoot.IsAllocated) { this.timerRoot.Free(); } } } } } } } [DefaultValue(100), SRDescription("TimerIntervalDescr"), SRCategory("CatBehavior")] public int Interval { get { return this.interval; } set { lock (this.syncObj) { if (value < 1) { object[] args = new object[] { value, 0.ToString(CultureInfo.CurrentCulture) }; throw new ArgumentOutOfRangeException("Interval", SR.GetString("TimerInvalidInterval", args)); } if (this.interval != value) { this.interval = value; if ((this.Enabled && !base.DesignMode) && (this.timerWindow != null)) { this.timerWindow.RestartTimer(value); } } } } } [SRCategory("CatData"), Localizable(false), Bindable(true), DefaultValue((string) null), TypeConverter(typeof(StringConverter)), SRDescription("ControlTagDescr")] public object Tag { get { return this.userData; } set { this.userData = value; } } // Nested Types private class TimerNativeWindow : NativeWindow { // Fields private Timer _owner; private bool _stoppingTimer; private int _timerID; private static int TimerID = 1; // Methods internal TimerNativeWindow(Timer owner) { this._owner = owner; } public override void DestroyHandle() { this.StopTimer(false, IntPtr.Zero); base.DestroyHandle(); } private bool EnsureHandle() { if (base.Handle == IntPtr.Zero) { CreateParams cp = new CreateParams { Style = 0, ExStyle = 0, ClassStyle = 0, Caption = base.GetType().Name }; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { cp.Parent = (IntPtr) NativeMethods.HWND_MESSAGE; } this.CreateHandle(cp); } return (base.Handle != IntPtr.Zero); } ~TimerNativeWindow() { this.StopTimer(); } private bool GetInvokeRequired(IntPtr hWnd) { if (hWnd != IntPtr.Zero) { int num; int windowThreadProcessId = SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, hWnd), out num); int currentThreadId = SafeNativeMethods.GetCurrentThreadId(); return (windowThreadProcessId != currentThreadId); } return false; } protected override void OnThreadException(Exception e) { Application.OnThreadException(e); } public override void ReleaseHandle() { this.StopTimer(false, IntPtr.Zero); base.ReleaseHandle(); } public void RestartTimer(int newInterval) { this.StopTimer(false, IntPtr.Zero); this.StartTimer(newInterval); } public void StartTimer(int interval) { if (((this._timerID == 0) && !this._stoppingTimer) && this.EnsureHandle()) { this._timerID = (int) SafeNativeMethods.SetTimer(new HandleRef(this, base.Handle), TimerID++, interval, IntPtr.Zero); } } public void StopTimer() { this.StopTimer(true, IntPtr.Zero); } public void StopTimer(bool destroyHwnd, IntPtr hWnd) { if (hWnd == IntPtr.Zero) { hWnd = base.Handle; } if (this.GetInvokeRequired(hWnd)) { UnsafeNativeMethods.PostMessage(new HandleRef(this, hWnd), 0x10, 0, 0); } else { lock (this) { if ((!this._stoppingTimer && (hWnd != IntPtr.Zero)) && UnsafeNativeMethods.IsWindow(new HandleRef(this, hWnd))) { if (this._timerID != 0) { try { this._stoppingTimer = true; SafeNativeMethods.KillTimer(new HandleRef(this, hWnd), this._timerID); } finally { this._timerID = 0; this._stoppingTimer = false; } } if (destroyHwnd) { base.DestroyHandle(); } } } } } protected override void WndProc(ref Message m) { if (m.Msg == 0x113) { if (((int) m.WParam) == this._timerID) { this._owner.OnTick(EventArgs.Empty); return; } } else if (m.Msg == 0x10) { this.StopTimer(true, m.HWnd); return; } base.WndProc(ref m); } // Properties public bool IsTimerRunning { get { return ((this._timerID != 0) && (base.Handle != IntPtr.Zero)); } } } }
如果你想要精确计时,并且长时间计时(比如使用服务器制作Windows Service等),需要使用System.Timers.Timer类)。
至于System.Thread.Timer类是一个由ThreadPool制作的类。它实现了IDispose接口,意味着你啥时候不用就可以调用把这个类回收。
System.Windows.Forms中的Timer是图形化的,计时并不精确。
If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer
Help by clicking:
Click here to donate your rice to the poor
Click to Donate
Click to feed Dogs & Cats- 已编辑 ThankfulHeartModerator 2013年4月15日 8:13
- 已标记为答案 大河向东流 2013年4月15日 8:29