這是怎麼回事?從委託內鎖定靜態對象不起作用
private static object Lock_HandleError = new object();
public static void HandleError(Exception ex)
{
lock(Lock_HandleError)
{
//IF the UI is processing a visual tree event (such as IsVisibleChanged), it throws an exception when showing a MessageBox as described here: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/44962927-006e-4629-9aa3-100357861442
//The solution is to dispatch and queue the MessageBox. We must use BeginInvoke because dispatcher processing is suspended in such cases.
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
{
lock(Lock_HandleError)
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate(){
HandleError(new Exception("testing purposes only"));
}, DispatcherPriority.Background);
MessageBox.Show(ex.Message, "Application Error", MessageBoxButton.OK, MessageBoxImage.Error);
//This point is not reached until the user clicks "OK"
}
}, DispatcherPriority.Background);
}
}
public void main()
{
HandleError(new Exception("The first error"));
}
上述代碼的預期的行爲是一個錯誤信息會出現在一個時間,當用戶點擊「確定」後,在Lock_HandleError
對象將得到派出線程釋放,下一調用HandleError可以繼續 - 但是我得到的是無限級錯誤消息,沒有打到「OK」。
爲什麼這個鎖不工作?
通過在每個鎖定語句的入口和出口處設置斷點,我可以清楚地看到代理正在調用lock()
,並再次調用一個新的「HandleError」調用,然後在MessageBox上暫停以等待用戶輸入。
與此同時,在另一個線程中,調度HandleError的調用得到運行 - 而不是像它應該那樣在lock()語句中等待,即使MessageBox委託清楚地放置了一個鎖並且還沒有發佈它。
我對我的多線程不太熟悉,但是我想知道是否可以嘗試在'BeginInvoke'方法中刪除'lock'? – Richard 2012-03-27 16:07:54
刪除鎖定並不能完成任何操作 - 因爲鎖定就像現在不存在一樣。雖然UI線程正在等待用戶在消息框中單擊「確定」,但它會處理來自應用程序其他區域的HandleError()的額外調用,並且我需要它停止並等待。 – Alain 2012-03-27 16:34:50
我試圖在這裏使用信號量來解決問題:http://stackoverflow.com/questions/9894750/how-can-i-get-the-ui-thread-to-wait-on-a-semaphore-but -process-additional-dispa – Alain 2012-03-27 17:48:54