WPF 전역 예외 처리
WinForm과 WPF는 동일하게 "Application"이라는 이름의 타입을 사용하긴 하지만, 사실 이름만 같을 뿐 전체적인 구현 자체는 완전히 다른 구조입니다. 물론, 예외 처리도 많이 달라졌습니다.
우선, 이 토픽을 더 읽으시기 전에 예전에 소개해 드렸던 다음의 자료를 먼저 읽어보시길 바랍니다.
Debug Features : 4. .NET 예외 처리 정리
; https://www.sysnet.pe.kr/2/0/316
중요한 것은 이 역시 ".NET Application"이기 때문에 기본적인 원칙은 벗어나지 않습니다. 즉, 모든 예외는 "AppDomain.CurrentDomain.UnhandledException"에서 처리되어질 수 있습니다.
하지만, WPF는 WinForm과 마찬가지로 Console 응용 프로그램 범주에 속하지 않습니다. 따라서 메시지 하나의 반응에 예외가 발생했다고 해서 전체 응용 프로그램 자체를 비정상 종료시킬 수는 없습니다. 그나마 WinForm에서는 Application.ThreadException을 통해서 UI 스레드에서 발생한 예외를 알아낼 수가 있고, Application.SetUnhandledExceptionMode를 통해서 예외 자체를 다시 rethrow 할 수 있도록 해주고 있는데요.
그렇다면, WPF에서는 어떻게 해야 처리되지 않은 예외로 인한 응용 프로그램의 비정상 종료를 막을 수 있을까요?
그 해답은 UI 스레드를 담당하고 있는 App.Dispatcher가 제공해 주고 있는데, 보통 아래와 같이 2개의 이벤트를 구독해서 처리해야 합니다.
public App()
{
this.Dispatcher.UnhandledException +=
new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
this.Dispatcher.UnhandledExceptionFilter +=
new DispatcherUnhandledExceptionFilterEventHandler(Dispatcher_UnhandledExceptionFilter);
}
void Dispatcher_UnhandledExceptionFilter(object sender,
DispatcherUnhandledExceptionFilterEventArgs e)
{
e.RequestCatch = true;
}
void Dispatcher_UnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.ToString());
e.Handled = true;
}
사실, 개인적으로 왜 위와 같이 2단계의 예외 처리 이벤트를 두었는지는 이해할 수가 없습니다. 간단하게 살펴보면, UnhandledExceptionFilter 단계에서는 선택적으로 "e.RequestCatch" 변수에 true / false를 할당하는 것이 가능한데, 만약 여기에 true를 주면 비정상 종료되지 않고 false를 주면 응용 프로그램이 비정상종료를 하게 됩니다.
또한, e.RequestCatch 변수의 값에 상관없이 Dispatcher_UnhandledException 이벤트 처리기는 호출이 되어집니다. 중요한 것은, 이때에도 e.Handled 변수에 true 값을 할당해 주어야만 응용 프로그램이 비정상 종료 하는 것을 막을 수가 있습니다. 왜 이렇게 2가지 단계로 나뉘어야만 했을까요? 보시면 알겠지만, UnhandledExceptionFilter 이벤트 처리기 단계에서도 DispatcherUnhandledExceptionFilterEventArgs 매개변수(e.Exception)를 통해서 예외를 알아낼 수가 있습니다. 그러니 굳이 Dispatcher_UnhandledException 단계까지 갈 필요가 없음에도 불구하고.
마지막으로... 퀴즈 하나!
WPF 응용 프로그램에서 secondary thread에서 예외가 발생한 경우에는 어떻게 처리할 수 있을까요?
[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]