另一種可能性是,有在WPF實現DispatcherTimer 的一個bug(有毫秒之間的不匹配和蜱引起視具體過程執行時間的潛在不準確),如下證明:
http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/DispatcherTimer.cs,143
class DispatcherTimer
{
public TimeSpan Interval
{
set
{
...
_interval = value;
// Notice below bug: ticks1 + milliseconds [Bug1]
_dueTimeInTicks = Environment.TickCount + (int)_interval.TotalMilliseconds;
}
}
}
http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs
class Dispatcher
{
private object UpdateWin32TimerFromDispatcherThread(object unused)
{
...
_dueTimeInTicks = timer._dueTimeInTicks;
SetWin32Timer(_dueTimeInTicks);
}
private void SetWin32Timer(int dueTimeInTicks)
{
...
// Notice below bug: (ticks1 + milliseconds) - ticks2 [Bug2 - almost cancels Bug1, delta is mostly milliseconds not ticks]
int delta = dueTimeInTicks - Environment.TickCount;
SafeNativeMethods.SetTimer(
new HandleRef(this, _window.Value.Handle),
TIMERID_TIMERS,
delta); // <-- [Bug3 - if delta is ticks, it should be divided by TimeSpan.TicksPerMillisecond = 10000]
}
}
http://referencesource.microsoft.com/#WindowsBase/Shared/MS/Win32/SafeNativeMethodsCLR.cs,505
class SafeNativeMethodsPrivate
{
...
[DllImport(ExternDll.User32, SetLastError = true, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr SetTimer(HandleRef hWnd, int nIDEvent, int uElapse, NativeMethods.TimerProc lpTimerFunc);
}
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx
uElapse [in]
Type: UINT
The time-out value, in milliseconds. // <-- milliseconds were needed eventually
但你只能確保線程睡眠至少爲x millioseconds;線程調度程序不會證明線程將以毫秒計數運行 – Wilhelm 2009-07-18 22:32:28
正確。我同意你所說的關於不能確定下一次滴答的時間。我所說的一點是,當您的下一個勾號發生時,您不希望執行先前勾號中的勾號事件代碼。 – 2009-07-20 13:51:26