2009-01-23 6 views
9

다소 큰 프로젝트에서 작업 중이므로 모든 것을 잡을 것 같지 않습니다. 처리되지 않은 예외를 알리는 이벤트를 발견했지만 프로그래밍 방식으로 Windows 오류 대화 상자를 종료 할 수있는 방법을 찾지 못했습니다. 이상적으로 처리되지 않은 예외가있는 경우 해당 이벤트가 시작되고 사용자에게 문제가 있음을 알리는 대화 상자를 제공 한 다음 정상적으로 닫으려고합니다. 이 일을 할 수있는 방법이 있습니까? 나는 try catch에서 가장 높은 레이어를 래핑 할 수 있다는 것을 알았지 만, 좀 더 우아한 것을 기대하고있었습니다."Microsoft에 오류 보고서 보내기"

답변

5

이것은 우리가 한 것입니다. 상업용 프로젝트로이 방출하는 경우

static void Main() { 
    try 
    { 
     SubMain(); 
    } 
    catch (Exception e) 
    { 
     HandleUnhandledException(e); 
    } 
} 

private static void SubMain() 
{ 
    // Setup unhandled exception handlers 
    AppDomain.CurrentDomain.UnhandledException += // CLR 
     new UnhandledExceptionEventHandler(OnUnhandledException); 
    Application.ThreadException += // Windows Forms 
     new System.Threading.ThreadExceptionEventHandler(
      OnGuiUnhandledException); 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new frmMain()); 
} 

// CLR unhandled exception 
private static void OnUnhandledException(Object sender, 
    UnhandledExceptionEventArgs e) 
{ 
    HandleUnhandledException(e.ExceptionObject); 
} 

// Windows Forms unhandled exception 
private static void OnGuiUnhandledException(Object sender, 
    System.Threading.ThreadExceptionEventArgs e) 
{ 
    HandleUnhandledException(e.Exception); 
} 
+1

왜 나는 downvoted을 얻었습니까? –

+0

왜 Try/Catch 블록에서 AppDomain.UnhandledException * 및 *을 모두 구현합니까? 그건 바보 같은 거위 야. –

3

귀하의 질문에 답변했습니다. 오류 대화 상자를 방지하는 가장 좋은 방법은 대화 상자가 나타나지 않도록 예외를 처리하는 코드를 작성하는 것입니다. 레이몬드 첸 (Raymond Chen)이 제안하는 것입니다 (내가 너무 대담 할 수 있다면).

+0

글로벌 try/catch (첫 번째 대답과 같음)가 내가 고려하고있는 것입니다. 나는 이것이 최선의 관행인지 아닌지 확실하지 않았습니다. 나는 그것을 할 수있는 더 깨끗한 방법이 있는지 확실하지도 않았다. – Steve

-2

당신은 그 끝이 ...이 나 작동하지 않을 수 있습니다 폼 DrWatson 일이다 마이크로 소프트 \ 윈도우 NT를 \ CurrentVersion \ AeDebug

\ HKEY_LOCAL_MACHINE \ 소프트웨어와 함께 연주 시도 할 수 있습니다.

+1

응용 프로그램 관련 문제를 해결하려는 경우 시스템 전체 설정을 사용하지 마십시오 –

+0

- 사용자가 설정을 변경한다고해서 사용자가 마음에 들지 않을 수 있습니다 ... - 응용 프로그램이이 레지스트리에 대한 쓰기 권한이 없을 수 있습니다. 키. –

0

질문이 WinForms 응용 프로그램에 관한 것이면 선택한 대답이 효과가 있지만 정확하게는 정확하지는 않습니다. 당신은 .NET 프레임 워크 2.0 이상을 사용하고 작업자 스레드에서 처리되지 않은 예외가있을 경우

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) 
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException 

And here's the MSDN Documentation on the method

1

, 난 당신을 믿지 :

.NET이 정확한 시나리오에 대한 보조를 제공합니다 운이 좋다. .NET 1.0 및 1.1에서 CLR은 단순히 주 스레드 이외의 스레드에서 예외를 삼켰습니다. 그러나 스레드에서 처리되지 않은 예외로 인해 응용 프로그램이 종료되는 .NET 2.0에서는이 기능이 변경되었습니다.

AppDomain.CurrentDomain.UnhandledException을 구독하면 이러한 종류의 처리되지 않은 예외가 발생할 때 알림을받을 수 있지만이 시점에서 응용 프로그램이 종료 될 가능성이 높으며 로깅과 같은 불가피한 작업을 수행 할 수있는 기회가 주어집니다 예외 장소 및 사용자 친화적 인 메시지를 표시합니다. UnhandledExceptionEventArgs에는 IsTerminating이라는 읽기 전용 속성이 있습니다.이 속성을 사용하면 응용 프로그램이 종료되는지 여부를 확인할 수 있습니다. 응용 프로그램이 종료되면 일반적으로 Microsoft 오류보고 대화 상자가 나타납니다.

권장하지 않지만 응용 프로그램 구성 파일에서 응용 프로그램 호환성 플래그를 설정하여 CLR 1.0 및 1.1의 동작 방식을 되돌릴 수 있습니다.

이 응용 프로그램이 처리되지 않은 예외의 경우에 종료하고 오류보고 대화 상자를 얻을 수있는 가능성을 감소하게해서는 안됩니다.

내 권장 사항은 코드에서 예상하고 처리 할 수있는 예외 만 잡아 내고 다른 것들은 거품을 일으키게하는 것입니다.

+0

작업자 스레드를 관리하는 방법에 따라 다릅니다. non-long-running 작업에 대한 필자가 선호하는 방법은 Delegate.BeginInvoke()를 사용하여 ThreadPool 스레드를 사용하여 비동기 작업을 수행하는 것입니다. 이 작업을 수행하면 스레드는 EndInvoke()를 호출 할 때 예외를 반환합니다. EndInvoke가 모든 BeginInvoke에 대해 호출되는지 확인해야합니다. 그렇게하지 않으면 리소스 누수가 발생할 수 있습니다. – STW

관련 문제