Timer控件的Start方法和Enabled属性有什么不同

该文章讨论了一个C#Timer组件的Start和Stop方法,它们通过Enabled属性来控制定时器的启停。虽然实现方式略有不同,但效果相同。文章提供了完整的代码示例,展示了如何使用Timer类以及其内部的工作机制,包括事件处理和线程安全的操作。

先说结果,

不同点

仅仅是一个通过方法处理问题,一个通过属性处理问题

相同点

效果相同

对应的代码如下


        public void Start()
        {
            Enabled = true;
        }

        public void Stop()
        {
            Enabled = false;
        }

通过代码可以知道,start也是通过调用Enabled属性来处理问题的。

完整的timer代码如下


using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;

namespace System.Windows.Forms
{
    [DefaultProperty("Interval")]
    [DefaultEvent("Tick")]
    [ToolboxItemFilter("System.Windows.Forms")]
    [SRDescription("DescriptionTimer")]
    public class Timer : Component
    {
        private class TimerNativeWindow : NativeWindow
        {
            private Timer _owner;

            private int _timerID;

            private static int TimerID = 1;

            private bool _stoppingTimer;

            public bool IsTimerRunning
            {
                get
                {
                    if (_timerID != 0)
                    {
                        return base.Handle != IntPtr.Zero;
                    }

                    return false;
                }
            }

            internal TimerNativeWindow(Timer owner)
            {
                _owner = owner;
            }

            ~TimerNativeWindow()
            {
                StopTimer();
            }

            private bool EnsureHandle()
            {
                if (base.Handle == IntPtr.Zero)
                {
                    CreateParams createParams = new CreateParams();
                    createParams.Style = 0;
                    createParams.ExStyle = 0;
                    createParams.ClassStyle = 0;
                    createParams.Caption = GetType().Name;
                    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                    {
                        createParams.Parent = (IntPtr)NativeMethods.HWND_MESSAGE;
                    }

                    CreateHandle(createParams);
                }

                return base.Handle != IntPtr.Zero;
            }

            private bool GetInvokeRequired(IntPtr hWnd)
            {
                if (hWnd != IntPtr.Zero)
                {
                    int lpdwProcessId;
                    int windowThreadProcessId = SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, hWnd), out lpdwProcessId);
                    int currentThreadId = SafeNativeMethods.GetCurrentThreadId();
                    return windowThreadProcessId != currentThreadId;
                }

                return false;
            }

            public void RestartTimer(int newInterval)
            {
                StopTimer(destroyHwnd: false, IntPtr.Zero);
                StartTimer(newInterval);
            }

            public void StartTimer(int interval)
            {
                if (_timerID == 0 && !_stoppingTimer && EnsureHandle())
                {
                    _timerID = (int)SafeNativeMethods.SetTimer(new HandleRef(this, base.Handle), TimerID++, interval, IntPtr.Zero);
                }
            }

            public void StopTimer()
            {
                StopTimer(destroyHwnd: true, IntPtr.Zero);
            }

            public void StopTimer(bool destroyHwnd, IntPtr hWnd)
            {
                if (hWnd == IntPtr.Zero)
                {
                    hWnd = base.Handle;
                }

                if (GetInvokeRequired(hWnd))
                {
                    UnsafeNativeMethods.PostMessage(new HandleRef(this, hWnd), 16, 0, 0);
                    return;
                }

                lock (this)
                {
                    if (_stoppingTimer || hWnd == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(new HandleRef(this, hWnd)))
                    {
                        return;
                    }

                    if (_timerID != 0)
                    {
                        try
                        {
                            _stoppingTimer = true;
                            SafeNativeMethods.KillTimer(new HandleRef(this, hWnd), _timerID);
                        }
                        finally
                        {
                            _timerID = 0;
                            _stoppingTimer = false;
                        }
                    }

                    if (destroyHwnd)
                    {
                        base.DestroyHandle();
                    }
                }
            }

            public override void DestroyHandle()
            {
                StopTimer(destroyHwnd: false, IntPtr.Zero);
                base.DestroyHandle();
            }

            protected override void OnThreadException(Exception e)
            {
                Application.OnThreadException(e);
            }

            public override void ReleaseHandle()
            {
                StopTimer(destroyHwnd: false, IntPtr.Zero);
                base.ReleaseHandle();
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 275)
                {
                    if ((int)(long)m.WParam == _timerID)
                    {
                        _owner.OnTick(EventArgs.Empty);
                        return;
                    }
                }
                else if (m.Msg == 16)
                {
                    StopTimer(destroyHwnd: true, m.HWnd);
                    return;
                }

                base.WndProc(ref m);
            }
        }

        private int interval;

        private bool enabled;

        internal EventHandler onTimer;

        private GCHandle timerRoot;

        private TimerNativeWindow timerWindow;

        private object userData;

        private object syncObj = new object();

        [SRCategory("CatData")]
        [Localizable(false)]
        [Bindable(true)]
        [SRDescription("ControlTagDescr")]
        [DefaultValue(null)]
        [TypeConverter(typeof(StringConverter))]
        public object Tag
        {
            get
            {
                return userData;
            }
            set
            {
                userData = value;
            }
        }

        [SRCategory("CatBehavior")]
        [DefaultValue(false)]
        [SRDescription("TimerEnabledDescr")]
        public virtual bool Enabled
        {
            get
            {
                if (timerWindow == null)
                {
                    return enabled;
                }

                return timerWindow.IsTimerRunning;
            }
            set
            {
                lock (syncObj)
                {
                    if (enabled == value)
                    {
                        return;
                    }

                    enabled = value;
                    if (base.DesignMode)
                    {
                        return;
                    }

                    if (value)
                    {
                        if (timerWindow == null)
                        {
                            timerWindow = new TimerNativeWindow(this);
                        }

                        timerRoot = GCHandle.Alloc(this);
                        timerWindow.StartTimer(interval);
                        return;
                    }

                    if (timerWindow != null)
                    {
                        timerWindow.StopTimer();
                    }

                    if (timerRoot.IsAllocated)
                    {
                        timerRoot.Free();
                    }
                }
            }
        }

        [SRCategory("CatBehavior")]
        [DefaultValue(100)]
        [SRDescription("TimerIntervalDescr")]
        public int Interval
        {
            get
            {
                return interval;
            }
            set
            {
                lock (syncObj)
                {
                    if (value < 1)
                    {
                        throw new ArgumentOutOfRangeException("Interval", SR.GetString("TimerInvalidInterval", value, 0.ToString(CultureInfo.CurrentCulture)));
                    }

                    if (interval != value)
                    {
                        interval = value;
                        if (Enabled && !base.DesignMode && timerWindow != null)
                        {
                            timerWindow.RestartTimer(value);
                        }
                    }
                }
            }
        }

        [SRCategory("CatBehavior")]
        [SRDescription("TimerTimerDescr")]
        public event EventHandler Tick
        {
            add
            {
                onTimer = (EventHandler)Delegate.Combine(onTimer, value);
            }
            remove
            {
                onTimer = (EventHandler)Delegate.Remove(onTimer, value);
            }
        }

        public Timer()
        {
            interval = 100;
        }

        public Timer(IContainer container)
            : this()
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }

            container.Add(this);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (timerWindow != null)
                {
                    timerWindow.StopTimer();
                }

                Enabled = false;
            }

            timerWindow = null;
            base.Dispose(disposing);
        }

        protected virtual void OnTick(EventArgs e)
        {
            if (onTimer != null)
            {
                onTimer(this, e);
            }
        }

        public void Start()
        {
            Enabled = true;
        }

        public void Stop()
        {
            Enabled = false;
        }

        public override string ToString()
        {
            string text = base.ToString();
            return text + ", Interval: " + Interval.ToString(CultureInfo.CurrentCulture);
        }
    }
} 

特刺激里

anlog

2023年2月25日

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值