2009-04-28 46 views
6

我們有一個桌面應用程序,在後臺線程中執行相當嚴格的一組計算。這個計算的部分是在我們通過互操作訪問的非託管庫中執行的。我們發現,當我們開始計算時,UI線程在計算期間變得沒有響應。我們的印象是框架將處理線程切換以允許UI繼續響應,但事實並非如此。我們發現我們可以插入一個Thread.Sleep(0)或Application.DoEvents()來允許UI響應。這有減緩計算的副作用。此外,由非託管代碼執行的部分計算可能需要長達30秒才能完成,並且在此期間應用程序始終無響應。整個計算可能需要兩到五分鐘才能完成。.NET線程模型和Application.DoEvents與Thread.Sleep

這導致以下問題:

  • 什麼是關於用戶界面和互操作的.NET框架的線程模型?
  • 我們在假定框架應該處理後臺和UI線程之間的線程切換時是否不正確?
  • 在這種情況下使用Thread.Sleep和Application.DoEvents有什麼區別,並且比其他的優先?
+0

注:非常古老的Q & A;尋找更新的討論,以獲得有關當前可用解決方案的良好答案。 – ToolmakerSteve 2018-03-03 21:55:58

回答

2

你可以降低你的後臺線程的優先級,所以它會被OS搶佔更多。如果您有某些領域知識會導致您希望在搶佔時進行控制,則可以使用Thread.Sleep(0),如果有另一個線程正在等待,那麼它將放棄您的時間片。

Application.DoEvents抽取Windows消息隊列。這會使您的應用程序響應按鍵或窗口大小等事件。 Thread.Sleep會導致你的線程被搶佔(或者,在Thread.Sleep(0)的情況下)。

利用回調,但還可以閱讀Threading in C#

0

正確的方法做,這是。查看使用異步方法的Silverlight模型(例如,用於檢索Web服務數據)。我知道這個問題是「回答」,但答案不是理想的恕我直言。

2

你最好的選擇是創建你自己的ThreadDoEventsThread.Sleep(0)會阻止計算,從而減慢計算速度。您可以將DLL調用包裝在ThreadStart委託或ParameterizedThreadStart委託中,並在實例化Thread時將委託名稱用作參數。從那裏,你所要做的就是致電Thread的Start方法。