另一种可能性是 DispatcherTimer 的 WPF 实现中存在错误(毫秒和滴答之间存在不匹配,导致潜在的不准确性,具体取决于确切的进程执行时间),如下所示:
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