2014-03-04 44 views
1

我在應用程序中註冊了一個錯誤處理程序,該程序在發生未處理的異常時顯示用戶對話框MessageBox。它連接到Application.DispatcherUnhandledException事件,因此發生在UI線程上。現在我已經看到了定期拋出異常的情況,每秒一次,並且新的對話框不斷彈出。我試圖用鎖來防止這種情況,但因爲它全部在同一個線程上,所以這沒有任何作用。在同一個線程上額外的睡眠鎖定顯然導致屏幕上單個阻塞的MessageBox。阻止一個線程上的多個MessageBox而不會阻止

MessageBox似乎釋放UI線程以顯示其他消息框。我怎樣才能防止沒有阻止線程?

用戶可以選擇繼續或退出應用程序。繼續時,下一個排隊的MessageBox應該出現,它不應該被丟棄。如果一次顯示太多的消息,用戶仍然可以決定退出應用程序。

+1

'平!平安!平安!平安!平!...... –

+0

沒錯。在Visual Studio中,我有「停止調試」按鈕,但普通用戶仍然很無奈。 – ygoe

+0

IIRC,如果消息處理程序彈出錯誤消息框,則該框會獲得焦點並運行其自己的消息循環。這似乎並沒有阻止更多已發佈到原始窗口的消息被分派到它,並因此生成更多的錯誤框。我同意這是一個PITA,並傾向於用一堆惱人的地毯填滿屏幕。恐怕我不知道任何停止此類行爲的方式,而不是保留錯誤狀態信息。以防止異常發生多次。 –

回答

0

消息框仍然是在您的線程上運行的窗口,因此它們必須抽取窗口消息(模態消息循環)以便在需要時重新繪製,移動,處理鍵盤輸入(例如Tab在控件之間移動),鼠標輸入。他們仍然在同一個線程上向其他窗口發送消息,以確保擁有它們的窗口被重新繪製。擁有窗口被禁用,所以輸入消息只會導致播放默認聲音,但定時器仍將被觸發,並且任何發送或發送的消息仍將被處理。

這種問題的常見原因是,您有一個System.Windows.Forms.Timer或WPF DispatcherTimer附加到窗口。其他可能性包括使用InvokeBeginInvoke在UI線程上執行某些操作的後臺線程。

+0

是的,這是問題的情況。你想提出什麼解決方案?我在你的回答中找不到它。 – ygoe

1

這裏的問題不在消息框中。這是當消息框仍然打開時發生的情況,而另一個異常已發生。在這種情況下,您的DispatcherUnhandledException處理程序會在相同的線程中重新輸入。

但是,用戶還沒有做出有關以前的錯誤的決定,以前的消息框仍然在等待他的輸入。您的調用堆棧看起來是這樣的:

 
=> DispatcherUnhandledExceptionHandler (current) 
MessageBox.Show 
DispatcherUnhandledExceptionHandler (previous) 

顯然,你不能從DispatcherUnhandledExceptionHandler (previous)返回,而不DispatcherUnhandledExceptionHandler (current)第一回:你在相同線程嵌套調用內。如果沒有用戶確認這個拳頭,就不能從DispatcherUnhandledExceptionHandler (current)退回來。

我可以想出解決此問題的一種方法,同時堅持您的問題要求。它是在另一個線程上顯示消息框,並在等待用戶選擇時阻止主線程的消息循環。通過這種方式,可以不再發生異常的主線程上,直到你獲得用戶的關於當前異常同意:

Application.Current.DispatcherUnhandledException += (s, e) => 
{ 
    this.IsEnabled = false; // disable the main window 
    try 
    { 
     var result = Task.Factory.StartNew(
      () => MessageBox.Show(
       e.Exception.Message, "Continue?", 
       MessageBoxButton.YesNo), 
      TaskCreationOptions.LongRunning).Result; // this blocks 
     if (result == MessageBoxResult.Yes) 
      e.Handled = true; 
    } 
    finally 
    { 
     this.IsEnabled = true; // enable the main window 
    } 
}; 

這是前瞻性的UI體驗醜陋,但它給你想要的工作流程。