我們有一個WPF和/或Winforms客戶端正在使用的庫。通過異步同步避免死鎖並防止UI響應
我們已經提供了類似的異步方法:我們也(不幸)提供的同步封裝方法
Task<int> GetIntAsync()
:
int GetInt();
基本上只是調用異步方法和調用其任務是.Result
。
我們最近意識到,在某些情況下,需要在主UI線程上運行GetIntAsync
中的某些代碼(它需要使用標記爲「Single」線程模型的傳統COM組件(即組件必須運行在主STA線程不是任何STA線程)
所以問題是,當GetInt()
被稱爲主線程,它會僵局因爲
- 的
.Result
塊爲主線, GetIntAsync()
中的代碼使用Dispatcher.Invoke
嘗試在主線程上運行。
同步方法已被佔用,因此將其刪除將是一個突破性更改。相反,我們選擇在我們的同步GetInt()
方法中使用WaitWithPumping以允許調用主線程來工作。
這個工作正常,除了從他們的UI代碼中使用GetInt()
的客戶端。以前,他們預計使用GetInt()
會使其UI停止響應 - 也就是說,如果他們從按鈕的單擊事件處理程序中調用GetInt()
,則他們會希望在處理程序返回之前不會處理任何Windows消息。現在消息被抽出,他們的UI 是響應,同樣的按鈕可以再次點擊(他們可能沒有編寫他們的處理程序是可重入的)。
如果有一個合理的解決方案,我們希望不會有我們的客戶需要在通話過程中的代碼對用戶界面響應於GetInt
問:
- 是否有方法做
WaitWithPumping
,將泵「調用主」消息,但不泵其他UI相關的消息? - 如果客戶端用戶界面的行爲與當前顯示的模式對話框一樣,儘管處於隱藏狀態(即用戶無法訪問其他窗口),那就足夠了。但是,從我閱讀的內容來看,您無法隱藏模式對話框。
- 你可以想到其他解決方法,將不勝感激。
謝謝。我確實看到了UI塊。不幸的是,試圖進入主線程的代碼使用主線程的Dispatcher Dispatcher.Invoke來進入主線程。我猜想做這個工作,我需要將該代碼更改爲使用SynchronizationContext,而不是主線程的Dispatcher。有什麼辦法可以使它與主線程的Dispatcher一起工作嗎? – 2013-02-12 17:33:28
@MattSmith你的代碼沒有特別的工作,因爲你正在使用主線程的調度程序。 – Servy 2013-02-12 18:28:42