WinForms 애플리케이션에서 모든 '처리되지 않은'예외를 포착하는 것을 어떻게 만들 수 있습니까?


85

지금까지 난 그냥 주위에 try / catch 블록을 넣어 Application.RunProgram.cs프로그램에 대한 진입 점. 이것은 디버그 모드에서 모든 예외를 충분히 포착하지만 디버그 모드없이 프로그램을 실행하면 예외가 더 이상 처리되지 않습니다. 처리되지 않은 예외 상자가 나타납니다.

이런 일이 일어나길 원하지 않습니다. 비디 버그 모드에서 실행할 때 모든 예외가 포착되기를 원합니다. 이 프로그램에는 여러 스레드가 있으며 가급적 모든 예외는 동일한 핸들러에 의해 포착됩니다. DB에 예외를 기록하고 싶습니다. 누구든지 이것을 수행하는 방법에 대한 조언이 있습니까?

답변:


110

ThreadException 문서 의 예제를 살펴보십시오 .

public static void Main(string[] args)
{
   // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new     
  ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

  // Set the unhandled exception mode to force all Windows Forms errors
  // to go through our handler.
  Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

  // Add the event handler for handling non-UI thread exceptions to the event. 
  AppDomain.CurrentDomain.UnhandledException += new       
  UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

디버깅이 더 쉬워 지므로 디버깅 할 때 예외를 포착하지 않는 것이 좋습니다. 다소 해킹이지만 위의 코드를 다음과 같이 래핑 할 수 있습니다.

 if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... }

디버깅 할 때 예외 포착을 방지합니다.


1
백그라운드 작업자를 만들고 dowork 이벤트 처리기에서 의도적으로 null 참조 예외를 발생 시켰습니다. 그러나 다음과 같은 설정에도 불구하고 AppDomain.CurrentDomain.UnhandledException에 의해 잡히지 않았습니다. Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler (Application_ThreadException); Application.SetUnhandledExceptionMode (UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler (CurrentDomain_UnhandledException);
Isaac Bolinger 2011-04-23

4
@IsaacB, 백그라운드 작업자는 자체적으로 예외를 포착합니다. RunWorkerCompleted에서도 RunCompletedEventArgs.Error 속성을보고 예외를 확인할 수 있습니다.
Can Gencer 2011

1
추가 스레드에 대한 예외 처리를 기본 양식의 OnLoad에 넣어 테스트 할 수 있습니다. new Thread (() => {throw new Exception ();}). Start ();
캔 Gencer

불행히도 UnhandledException을 처리해도 응용 프로그램이 종료되지는 않습니다. :(
Nazar Grynko 2013

7
FriendlyName.EndsWith 해킹 대신 Debugger.IsAttached를 사용해보십시오.
moltenform

27

NET 4에서는 특정 예외가 더 이상 기본적으로 포착되지 않습니다. 이는 AccessViolationException과 같이 실행 파일의 (치명적일 수있는) 손상된 상태를 나타내는 예외 인 경향이 있습니다.

메인 메소드 앞에 [HandleProcessCorruptedStateExceptions] 태그를 사용해보십시오.

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions

[HandleProcessCorruptedStateExceptions]
public static int Main()
{
    try
    {
        // Catch any exceptions leaking out of the program
        CallMainProgramLoop();
    }
    catch (Exception e) // We could be catching anything here
    {
        System.Console.WriteLine(e.Message);
        return 1;
    }
    return 0;
  } 

내가 사용할 수 AppDomain.CurrentDomain.UnhandledExceptionApplication.ThreadException너무와 [HandleProcessCorruptedStateExceptions]태그?
Kiquenet

18

좋은 예는 http://www.csharp-examples.net/catching-unhandled-exceptions/ 에서 찾을 수 있습니다 . 기본적으로 메인을 다음과 같이 변경하십시오.

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new Form1());
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
    }

9

이를 위해 NBug 라이브러리를 사용할 수 있습니다 . 다음과 같은 최소한의 설정으로 :

NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;

클라이언트에 배포 된 경우에도 애플리케이션에서 처리되지 않은 모든 버그에 대한 정보 수집을 시작할 수 있습니다. 타사 라이브러리를 사용하지 않으려면 아래 이벤트에 첨부해야합니다.

// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());

1
천만에요. 추가 질문이있는 경우 NBug 프로젝트 토론 포럼 ( nbusy.com/forum/f11 )을 사용하거나 여기에서 [nbug] 태그를 사용하세요.
Teoman Soygul 2011-04-23

물론 UnhandledException 이벤트에 "일반"이벤트 처리기를 구독 할 수도 있습니다. msdn.microsoft.com/en-us/library/…
neo2862 2011

Win7 + VS10 사용자 여러분,이 이벤트를 구독하면 구독이 실행되지 않고 대신 일반 Windows Vista / 7 대화 상자가 나타납니다. Check Online for a Solution또는 Close the Program.. 등. 구독하지 않으면 일반 일반 .NET 처리되지 않은 예외가 발생합니다. 창문. 이것은 릴리스 및 디버그 빌드 모두에서 발생하며 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);아무것도 변경하지 않음 설정을 시도했습니다 .
기드온 2011-04-23

@giddy, 예외를 처리 한 후 Environment.Exit (1)로 응용 프로그램을 종료해야합니다. 오류 창을 표시하지 않으려면.
Teoman Soygul 2011-04-23

@Teo 답장을 보내 주셔서 감사합니다. 내 오류 양식을 표시하고 앱을 종료하고 싶습니다. 그러나 이벤트 구독은 실행되지 않고 예외가 발생하면 일반 Win Vista / 7 대화 상자 만 표시합니다. 그러나 구독하지 않으면 일반 .NET 처리되지 않은 예외 대화 상자가 나타납니다!
기드온
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.