Dot-Net

確保事物在 WPF 中的 UI 執行緒上執行

  • March 4, 2010

我正在建構一個 WPF 應用程序。我正在與伺服器端進行一些非同步通信,並在客戶端使用事件聚合和 Prism。這兩件事都會導致生成不是 UI 執行緒的新執行緒。如果我嘗試在這些回調和事件處理程序執行緒上執行“WPF 操作”,那麼世界將分崩離析,現在它已經開始這樣做了。

首先,我在嘗試從伺服器的回調中創建一些 WPF 對象時遇到了問題。有人告訴我執行緒需要在 STA 模式下執行。現在我正在嘗試更新 Prism 事件處理程序中的一些 UI 數據,我被告知:

呼叫者無法訪問該執行緒,因為另一個執行緒擁有它。

所以; **在 WPF 中做正確的事情的關鍵是什麼?**我已經閱讀了這篇 MSDN 文章中的 WPF Dispatcher 。我開始明白了,但我還不是巫師。

  1. 當我需要執行一些我不確定是否會在 UI 執行緒上呼叫的東西時,總是使用 Dispatcher.Invoke 的關鍵是什麼?
  2. 如果它實際上是在 UI 執行緒上呼叫的,並且無論如何我都執行 Dispatcher.Invoke,這有關係嗎?
  3. Dispatcher.Invoke = 同步。Dispathcher.BeginInvoke = 非同步?
  4. Dispatcher.Invoke 會請求 UI 執行緒,然後停止等待嗎?響應速度較慢的程序是不好的做法和風險嗎?
  5. 無論如何,我如何獲得調度員?Dispatcher.CurrentDispatcher 是否總是給我代表 UI 執行緒的調度程序?
  6. 是否會存在多個 Dispatcher,或者“Dispatcher”是否與應用程序的 UI 執行緒基本相同?
  7. BackgroundWorker 是怎麼回事?我什麼時候改用這個?我認為這總是非同步的?
  8. 在 UI 執行緒上執行的所有內容(通過被呼叫)是否會在 STA 單元模式下執行?即,如果我有一些需要在 STA 模式下執行的東西 - Dispatcher.Invoke 就足夠了嗎?

有人想為我澄清事情嗎?有沒有相關推薦之類的?謝謝!

一個一個地檢查你的每個問題:

  1. 不完全的; 您應該只在必要時呼叫 UI 執行緒。見#2。
  2. 是的,這很重要。你不應該只是自動Invoke的一切。關鍵是僅在必要時呼叫 UI 執行緒。為此,您可以使用Dispatcher.CheckAccess方法。
  3. 那是正確的。
  4. 也是正確的,是的,您確實冒著響應速度較慢的程序的風險。大多數情況下,您不會看到嚴重的性能損失(我們談論的是上下文切換的毫秒數),但只有Invoke在必要時才應該這樣做。話雖如此,在某些時候這是不可避免的,所以不,我不會說這是不好的做法。這只是您不時遇到的問題的一種解決方案。
  5. 在我所見過的每一個案例中,我都應得的Dispatcher.CurrentDispatcher。對於復雜的場景,這可能還不夠,但我(個人)還沒有看到它們。
  6. 不完全正確,但這種構想不會造成任何傷害。讓我這樣說吧:Dispatcher 可以用來獲得對應用程序 UI 執行緒的訪問權限。但它本身並不是 UI 執行緒。
  7. BackgroundWorker通常在您有一個耗時的操作並希望在後台執行該操作時保持響應式 UI 時使用。通常,您不會使用 BackgroundWorker來代替Invoke,而是將 BackgroundWorkerInvoke 結合使用。也就是說,如果您需要更新 BackgroundWorker 中的某些 UI 對象,您可以呼叫 UI 執行緒,執行更新,然後返回原始操作。
  8. 是的。根據定義,WPF 應用程序的 UI 執行緒必須在單執行緒單元中執行。

有很多要說的BackgroundWorker,我相信很多問題已經涉及到它,所以我不會太深入。如果您好奇,請查看MSDN 頁面的 BackgroundWorker 類

引用自:https://stackoverflow.com/questions/2382663