gpt4 book ai didi

c# - WPF 接口(interface)仅在 DispatcherTimer 线程完成后更新

转载 作者:行者123 更新时间:2023-12-03 10:28:59 25 4
gpt4 key购买 nike

我有一个 WPF 应用程序,并且正在使用 .NET Framework 4.0 和 C#。我的应用程序由一个带有多个控件的界面组成。特别是我有一个任务需要每 10 秒定期执行一次。为了执行它,我使用了 System.Windows.Threading.DispatcherTimer . ViewModel 看起来像这样:

public class WindowViewModel {
protected DispatcherTimer cycle;

public WindowViewModel() {
this.cycle = new DispatcherTimer(DispatcherPriority.Normal,
System.Windows.Application.Current.Dispatcher);
this.cycle.Interval = new TimeSpan(0,0,0,0,10000);
this.cycle.Tick += delegate(object sender, EventArgs e) {
for (int i = 0; i < 20; i++) {
// Doing something
}
};
this.cycle.Start;
}
}

正如我所说,定期调用的例程会做一些事情。特别是那里有一些繁重的逻辑导致该例程需要几秒钟才能执行和完成。好吧,这是一个不同的线程,所以我应该没问题,界面不应该卡住。

问题是该例程会导致 View 模型被更新。更新了几个数据,对应的 View 就绑定(bind)到这些数据上。发生的情况是,当例程完成时,所有更新的数据都会一次刷新一次。我希望在线程执行期间更新数据。

特别是在那个例程中,我有一个 for循环。那么在循环退出时,界面中的所有内容都会更新。如何做到这一点?我在哪里做错了?

最佳答案

DispatcherTimer使用提供的 Dispatcher运行计时器回调。

如果您查看 Dispatcher 的文档,有一个线索:

Provides services for managing the queue of work items for a thread.



因此,通过使用 System.Windows.Application.Current.Dispatcher ,您正在使用为 UI 线程管理“工作项队列”的调度程序。

ThreadPool 中运行您的工作相反,您可以使用 System.Threading.Timer或使用 ThreadPool.QueueUserWorkItem在您的 DispatcherTimer打回来。

如果将其与以下扩展方法结合使用,则在完成繁重的工作负载后,很容易将任何 UI 特定的内容编码回 Dispatcher:
public static class DispatcherEx
{
public static void InvokeOrExecute(this Dispatcher dispatcher, Action action)
{
if (dispatcher.CheckAccess())
{
action();
}
else
{
dispatcher.BeginInvoke(DispatcherPriority.Normal,
action);
}
}
}

然后...
this.cycle.Tick += delegate(object sender, EventArgs e) {
ThreadPool.QueueUserWorkItem(_ => {
for (int i = 0; i < 20; i++) {
// Doing something heavy
System.Windows.Application.Current.Dispatcher.InvokeOrExecute(() => {
//update the UI on the UI thread.
});
}
});
};

关于c# - WPF 接口(interface)仅在 DispatcherTimer 线程完成后更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17106071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com