简单的 DispatchTimer Ticks 仅在 Win10 中不稳定 WPF
Simple DispatchTimer Ticks are erratic WPF in Win10 only
我在Win7和Win10上都试过了。在 Win7 上按我的想法工作,每 100 毫秒调用一次 Tick。但是在 win10 上,Tick 在 运行 处被调用了 2 次,然后停止,直到我将鼠标悬停在应用程序上,这会触发另一个 Tick 1 次。这很奇怪。
我正在使用 System.Windows.Threading。
所有代码都在代码隐藏中以对其进行测试,这一切都是为了保持简单:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TimerGeneral(true);
}
public DispatcherTimer timer = new DispatcherTimer();
int s;
public void TimerGeneral(bool estado)
{
timer.Interval = TimeSpan.FromMilliseconds(100);
if (estado && !timer.IsEnabled) { timer.Tick += timer_Tick; timer.Start(); }
else if (!estado && timer.IsEnabled) { timer.Stop(); }
}
public void timer_Tick(object sender, EventArgs e)
{
Debug.WriteLine("tick" + s++);
}
}
我有点迷茫为什么 Win10 工作方式不同,抱歉。
请记住,当使用默认构造函数实例化 DispatcherTimer
时(就像您所做的那样),计时器的 Dispatcher
将默认与 DispatcherPriority.Background
一起执行!因此延迟很高。
使用适当的构造函数指定更高的优先级:
var dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, Application.Current.Dispatcher)
这应该可以解决您的问题。
如果延迟仍然太高,请尝试 DispatcherPriority.Send
(谨慎使用)。
如果一个操作发布到 DispatcherPriority.Send
的 Dispatcher
,该操作绕过队列并立即执行。
根据计时器间隔和工作量,DispatcherPriority
应尽可能低,以防止 UI 变得迟钝。
或者,如果 Timers.Timer
或任何其他计时器更适合您,那么就使用它。您可以使用 Application.Current.Dispatcher.Invoke(Action)
或 Application.Current.Dispatcher.InvokeAsync(Action)
.
执行 UI 相关代码
我在Win7和Win10上都试过了。在 Win7 上按我的想法工作,每 100 毫秒调用一次 Tick。但是在 win10 上,Tick 在 运行 处被调用了 2 次,然后停止,直到我将鼠标悬停在应用程序上,这会触发另一个 Tick 1 次。这很奇怪。
我正在使用 System.Windows.Threading。
所有代码都在代码隐藏中以对其进行测试,这一切都是为了保持简单:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TimerGeneral(true);
}
public DispatcherTimer timer = new DispatcherTimer();
int s;
public void TimerGeneral(bool estado)
{
timer.Interval = TimeSpan.FromMilliseconds(100);
if (estado && !timer.IsEnabled) { timer.Tick += timer_Tick; timer.Start(); }
else if (!estado && timer.IsEnabled) { timer.Stop(); }
}
public void timer_Tick(object sender, EventArgs e)
{
Debug.WriteLine("tick" + s++);
}
}
我有点迷茫为什么 Win10 工作方式不同,抱歉。
请记住,当使用默认构造函数实例化 DispatcherTimer
时(就像您所做的那样),计时器的 Dispatcher
将默认与 DispatcherPriority.Background
一起执行!因此延迟很高。
使用适当的构造函数指定更高的优先级:
var dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, Application.Current.Dispatcher)
这应该可以解决您的问题。
如果延迟仍然太高,请尝试 DispatcherPriority.Send
(谨慎使用)。
如果一个操作发布到 DispatcherPriority.Send
的 Dispatcher
,该操作绕过队列并立即执行。
根据计时器间隔和工作量,DispatcherPriority
应尽可能低,以防止 UI 变得迟钝。
或者,如果 Timers.Timer
或任何其他计时器更适合您,那么就使用它。您可以使用 Application.Current.Dispatcher.Invoke(Action)
或 Application.Current.Dispatcher.InvokeAsync(Action)
.