先说结果,
不同点
仅仅是一个通过方法处理问题,一个通过属性处理问题
相同点
效果相同
对应的代码如下
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日
该文章讨论了一个C#Timer组件的Start和Stop方法,它们通过Enabled属性来控制定时器的启停。虽然实现方式略有不同,但效果相同。文章提供了完整的代码示例,展示了如何使用Timer类以及其内部的工作机制,包括事件处理和线程安全的操作。
2万+

被折叠的 条评论
为什么被折叠?



