2013-03-22 2 views
4

질문을 다루는 주제가 많이 있습니다. 그러나 그럼에도 불구하고 나는 문제가있다.AppDomain 처리되지 않은 예외

나는이 같은 새로운 AppDomain에 어셈블리를로드 :

public void Run() 
{ 
    //There's the problem. 
    //As Panos Rontogiannis mentioned the thread is created in default AppDomain 
    new Thread(RunApp).Start(); 
} 

private void RunApp() 
    try 
    { 
     AppDomain.CreateDomain("domain name").ExecuteAssembly("path to assembly"); 
    } 
    catch (Exception _e) 
    { 
     MessageBox.Show("Unhandled Exception.\n" + _e); 
    } 
} 

를로드 어셈블리의 Main 메서드에서 나는 UnhandledException 이벤트에 내 핸들러를 구독 :

AppDomain.CurrentDomain.UnhandledException += handleException; 

핸들러를 자체 :

public static void handleException(object a_s, UnhandledExceptionEventArgs a_args) 
{ 
    var _e = (Exception)a_args.ExceptionObject; 
    //Static loger class method 
    Loger.WriteError(_e.GetType().ToString(), _e.Message, "default solution"); 
} 

하지만 어디에서나 예외가 throw됩니다. 그는 핸들러가 관여하지 않는 어셈블리를로드했습니다. 예외 (default)는 AppDomain (첫 번째 try{} catch{})입니다.

답변

0

내 처리기는 예외가 처리 될 때 호출되지 않습니다. By upper the {} catch {}.

0

나는 핸들러가 호출되지 않는 이유를 정확히 이해하지 못했습니다.

로드 된 어셈블리의 Main 메서드에서 UnhandledException 대신 FirstChanceException을 사용하여 종료했습니다. 이처럼 :

AppDomain.CurrentDomain.FirstChanceException += 
    (obj, e) => Loger.WriteError(
     e.Exception.ToString(), 
     e.Exception.Message, 
     "default solution" 
    ); 
+0

당신의 생각에 맞을지 모르지만 나는 그것을 의심합니다. 첫 번째 기회 예외 사건은 발견되지 않은 예외와 동일하지 않습니다. 간단히 말해, 모든 예외가 발생할 때마다이 이벤트가 발생합니다.이 이벤트는 코드에 의해 처리되지 않고 종료됩니다 (재실행없이 블록 잡기). –

+0

글쎄요, 로깅 용도로만 사용 했으므로 괜찮습니다. 예외가 발생하면 로그되고 핸들러가 계속 작동합니다. – wazelin

+0

네,하지만 (.net 프레임 워크 자체조차도) 일부 코드는 예외를 내부적으로 사용한다는 것을 기억하십시오.이 코드는 표면을 가리고 "가짜"예외로 로깅을 가릴 수 있습니다. 물론 마일리지가 다를 수 있습니다. –

3

대부분의 아마, 당신은 새로운 AppDomain에서 예외를 처리 할 수없는 이유는 그것이 그 AppDomain에서 만든 스레드에서 발생되지 않는 것입니다. AppDomain.UnhandledException에 대한 문서에서 볼 때 매우 직설적 인 것은 아닙니다. 흥미로운 부분은 다음 : 예외가 스레드의 전체 스택이 가 적용 예외 핸들러를 찾지 못하고 풀린있다, 그래서 이벤트가 제기 될 수있는 먼저 응용 프로그램에있는 경우에만 처리되지 않은 것입니다

domain 스레드가 시작된 곳.

지금 발생 코드를 실행하는 스레드에서 만든 경우 기본 AppDomain (콘솔 응용 프로그램의 메인 스레드처럼), 다음 주 AppDomain에서 핸들러를 추가해야합니다. 던져진 예외 유형이 기본 AppDomain에로드되지 않은 경우 .NET의 어셈블리 로더는 응용 프로그램의 기본 디렉터리 및 프로빙 경로에서로드하려고 시도합니다. 이러한 자식이 AppDomain 자식과 같지 않으면 어셈블리가 확인되지 않고 (다른) 예외가 throw됩니다.

+0

네 말이 맞아. 'ExecuteAssembly'는 디폴트'AppDomain'에서 생성 된 새로운'Thread'에서 호출됩니다. 그러나 새로운'AppDomain'에로드 된 assebly 내부의 예외 사항을 막는 것이 중요합니다. – wazelin

+0

@Wazelin 그것을 처리하면 간단히 기록 할 수 있습니다. 처리되지 않은 예외로 수행 할 수있는 작업은 많지 않습니다. AppDomain은 운명에 처해 있으며 자식 AppDomain에서 생성 된 스레드에서 unhanlded 예외가 발생하면 응용 프로그램도 마찬가지입니다. 응용 프로그램을 다른 코드와 분리하려면 다른 프로세스로 작업해야합니다. –

0

이것은 늦은 답변이지만 ExecuteAssembly가 호출되기 전에 예외 처리기를 등록해야하는 경우 (VS2012/.NET 4.5) 저에게 묻는다면 정상적으로 작동하는 것 같습니다. 널 심판 (안전하지 않은 코드)를 작성하여 액세스 위반은 충돌을 강제로 그리고 아래 HandleException을 트리거 :

public static void HandleException(object a_s, UnhandledExceptionEventArgs a_args) 
{ 
    var _e = (Exception)a_args.ExceptionObject; 
    Console.WriteLine(_e.GetType().ToString(), _e.Message, "default solution"); 
} 

public void StarProcessWithinAppDomain(string fileName) 
{ 
    try 
    { 
     // New appdoamin/check exception isolation level 
     AppDomain sandBox = AppDomain.CreateDomain("sandBox"); 
     try 
     { 
      AppDomain.CurrentDomain.UnhandledException += HandleException; 
      sandBox.ExecuteAssembly(fileName); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("An error occurred (inner) within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName); 
     } 
     finally 
     { 
      AppDomain.Unload(sandBox); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine("An error occurred within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName); 
    } 
} 
0
  1. FirstChanceException 화재.
  2. catch 블록이 실행됩니다.
  3. 경우 블록의 어떤 catch 블록 또는 throwUnhandledException 화재

귀하의 catch 블록 UnhandledException가 발생하지 않도록합니다.