我在C#中編寫了一個Windows Forms應用程序,該應用程序執行大量長時間運行的過程。我需要編寫應用程序,以便GUI不鎖定。編程它的最佳方式是什麼?如何編程異步Windows Forms應用程序?
我知道如何使用下列內容:
BeginInvoke
/EndInvoke
- 調用
Application.DoEvents()
反覆(可能不是一個好主意) BackgroundWorker
- 等
但如何通過回叫等來管理GUI狀態......並不是微不足道的。是否有解決方案(以模式或庫的形式)?
我在C#中編寫了一個Windows Forms應用程序,該應用程序執行大量長時間運行的過程。我需要編寫應用程序,以便GUI不鎖定。編程它的最佳方式是什麼?如何編程異步Windows Forms應用程序?
我知道如何使用下列內容:
BeginInvoke
/EndInvoke
Application.DoEvents()
反覆(可能不是一個好主意)BackgroundWorker
但如何通過回叫等來管理GUI狀態......並不是微不足道的。是否有解決方案(以模式或庫的形式)?
Model-View-Controller pattern將UI的狀態與UI的視覺方面分開。只要你的MVC實現是線程感知的,它應該爲你解決狀態管理問題。
這就是我如何處理多線程的UI實現。
編輯:這是good post關於爲WinForms項目選擇MVC實現。
使用ThreadPool從UI中觸發長時間運行的進程是相對簡單的。如果您需要反饋,可以使用一些事件處理程序從長時間運行的進程中觸發某些事件,然後註冊並根據需要更新UI。
MVC很好,但你仍然需要確保你的進程在UI線程以外的線程上觸發。
所有的選項都是做同樣事情的語法糖(異步執行)。可能會有不同程度的控制。我會去BackgroundWorker,因爲你的GUI(由主線程處理)將始終是響應式的。
使用BackgroundWorker
是最簡單的方法來做你想做的事情。 BackgroundWorker
簡化了處理線程的邏輯,讓您只需很少的代碼即可編寫代碼。你只需要處理三個事件(DoWork
,ProgressChanged
和RunWorkerCompleted
),並遵循幾個原則:
ReportProgress
,並在UI邏輯中處理ProgressChanged
事件。RunWorkerCompletedEventArgs
的Error
屬性非常重要。如果你不這樣做,你就不會知道你的方法失敗了。CancellationPending
屬性以查看是否已請求取消。如果有,一旦完成處理取消操作,請在DoWorkEventArgs
對象上設置Cancel
屬性。請注意,有可能CancellationPending
爲真,Cancel
爲假;例如,當用戶請求取消並且該方法在它有機會檢查CancellationPending
之前完成時發生這種情況。Cancel
在RunWorkerCompleted
事件處理程序,讓你的UI可以提供,而工人正在運行什麼事適當的反應。文檔中的示例都顯示調用窗體方法的DoWork
事件處理函數。這幾乎肯定不是你想要做的。一般來說,將業務邏輯與用戶界面分離是一個好主意;在後臺任務中這是至關重要的。如果你的長時間運行的方法是一個不知道UI甚至存在的類的成員,那麼你就不會有無意中讓它調用更新狀態欄或其他方法的方法。
啊哈... that'w什麼MVC是。行..很多謝謝。 – Nestor 2009-10-04 20:54:14