[英]How run async Task on WPF without hanging gui
我有用于监控数据的 WPF 应用程序,我在 Loaded 方法中编写Task.Run
来完成工作并在 GUI 中显示数据。
代码如下所示:
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await Task.Run(() => DoAddAsync());
}
void DoAddAsync()
{
while (true)
{
this.Dispatcher.Invoke(() =>
{
//Do Some
});
}
}
它工作正常,我可以在不挂起的情况下更改 GUI 中的组件。
但是,如果我在this.Dispatcher.Invoke
执行一个方法,GUI 就会挂起,在该方法关闭之前我什么也做不了。
任何人都可以帮助我在不挂 GUI 的情况下运行this.Dispatcher.Invoke
方法?
您可以使用异步循环。 尽管这看起来像一个无限循环,但实际上不是。 由于延迟任务的等待,此方法定期将控制权交还给其调用者。 如果这不是具有有效异步操作的异步方法,那么它将是一个同步方法,并且在我们调用它时会死锁 UI。
但由于它不是,它可以根据需要工作,并为您提供代码应该做什么的非常清晰的意图,并让我们始终保持在 UI 线程上(等待的魔力!)所以我们不有多线程问题或多个委托/回调。
private async Task DoAddAsync()
{
while (true)
{
// do the work in the loop
// ....
// don't run again for at least 200 milliseconds
await Task.Delay(200);
}
}
但是,使这项工作发挥作用的真正技巧不在 DoAddAsync 方法中。 它是我们如何称呼它的。 您无需等待对它的调用。
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
DoAddAsync()
}
你也可以更新你的方式,但它会引入多个委托,潜在的多线程复杂性取决于正在完成的工作,我们仍然必须回到 UI 线程来更新 UI。
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await Task.Run(async () =>
{
while (true)
{
// do the work in the loop
// update the UI on the UI thread
Dispatcher.Invoke(() => // do some );
// don't run again for at least 200 milliseconds
await Task.Delay(200);
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.