[英]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.