簡體   English   中英

如何在不掛 gui 的情況下在 WPF 上運行異步任務

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM