2010-03-22 82 views
1

winforms對話框正在使用BackgroundWorker執行一些異步操作並取得重大成功。有時,由後臺工作人員運行的異步進程需要將事件引發到用戶響應的WinForms應用程序(詢問用戶是否希望取消的消息),其響應在事件的CancelEventArgs類型中捕獲。作爲一個線程的實現,我會期待工人的RaiseEvent被觸發,然後工作者會繼續,因此需要我暫停工作,直到收到響應。但是,工作人員會等待由加註事件執行的代碼完成。BackgroundWorker引發的事件未在預期線程上執行

看起來好像是我通過事件調用調用的方法實際上是由後臺工作人員使用的工作線程,我很驚訝,因爲我期望在主線程正在運行的主線程上看到它。另外令人驚訝的是,沒有交叉線程異常拋出。

有人能解釋爲什麼這不是我所期望的嗎?

回答

2

BackgroundWorker的將提高其ProgressChanged事件,並在UI線程上RunWorkerCompleted事件(更準確地說,它會把它們張貼到使用當前建立的SynchronizationContext線程)。

但它不會簡單地讓你提高任意UI線程上的事件。爲此,您應該訪問SynchronizationContext.Current並使用Post方法。

+0

謝謝Josh,看起來不錯,明天我會看看。我仍然感到驚訝的是,當我從該事件調用Windows.Forms.Messagebox.Show時,因爲它仍然位於後臺線程中,所以未引發交叉線程異常。 – Topdown 2010-03-22 11:23:24

+0

有沒有這樣的事情作爲「UI線程」,只是碰巧是一個線程,你只能從UI運行。任何線程都可以調用像MessageBox之類的UI東西,或者創建並顯示WinForms。同樣,您的工作線程並不真正知道它正在運行異步,因此事件被引發,就像它正在正常運行一樣。 – 2010-03-22 13:00:31

+0

從技術上來說,Chris是正確的,但是從一個當前沒有消息循環的線程調用MessageBox.Show會導致創建一個(否則MessageBox將無法工作),所以我同意如果有非法的檢查會很好跨線程訪問Windows窗體控件的工作方式。 – Josh 2010-03-22 14:19:44