這裏的問題不在消息框中。這是當消息框仍然打開時發生的情況,而另一個異常已發生。在這種情況下,您的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體驗醜陋,但它給你想要的工作流程。
'平!平安!平安!平安!平!...... –
沒錯。在Visual Studio中,我有「停止調試」按鈕,但普通用戶仍然很無奈。 – ygoe
IIRC,如果消息處理程序彈出錯誤消息框,則該框會獲得焦點並運行其自己的消息循環。這似乎並沒有阻止更多已發佈到原始窗口的消息被分派到它,並因此生成更多的錯誤框。我同意這是一個PITA,並傾向於用一堆惱人的地毯填滿屏幕。恐怕我不知道任何停止此類行爲的方式,而不是保留錯誤狀態信息。以防止異常發生多次。 –