2017-05-05 1 views
4

시도 - 캐치 :catch에서 마지막으로 throw 된 예외입니다. 대 CLR 행동 나는 간단한 C# 콘솔 응용 프로그램을 작성 블록

class Mystery 
{ 
    static void Main(string[] args) 
    { 
     MakeMess(); 
    } 

    private static void MakeMess() 
    { 
     try 
     { 
      System.Console.WriteLine("try"); 
      throw new Exception(); // let's invoke catch 
     } 
     catch(Exception) 
     { 
      System.Console.WriteLine("catch"); 
      throw new Exception("A"); 
     } 
     finally 
     { 
      System.Console.WriteLine("finally"); 
      throw new Exception("B"); 
     } 
    } 
} 

콘솔에 주어진 출력은 다음과 같습니다

캐치

처리되지 않은 예외를 시도 : System.Exception : A에서 Mystery.Program.MakeMess() ...

CLR이 A에 걸렸으며 finally 블록이 전혀 호출되지 않은 것으로 보입니다. 내가 시도-catch 블록으로 MakeMess()로 전화를 서라운드

는하지만 :

static void Main(string[] args) 
{ 
    try 
    { 
     MakeMess(); 
    } 
    catch(Exception ex) 
    { 
     System.Console.WriteLine("Main caught " + ex.Message); 
    } 
} 

는 출력은 완전히 다른 같습니다

시도

캐치

마지막으로

메인 잡힌 B

Exception이 메소드 외부에서 엄격하게 처리 될 때 MakeMess()에서 전파되는 Exception이 다른 것처럼 보입니다.

이 동작에 대한 설명은 무엇입니까?

+0

컴파일러 외부에서 실행하면 어떻게됩니까? 나는 마침내 쓰여질 것이라고 가정한다. – TheLethalCoder

+2

http://stackoverflow.com/a/1555578/613130를 참조한다. * 중요한 것은 e가 호출 스택 위로 try/catch 블록에 의해 포착되지 않거나 전역 적으로 처리된다면 예외 처리기를 호출하면 finally 블록이 전혀 실행되지 않을 수 있습니다. * – xanatos

+0

catch 내에서 예외를 catch하지 않았습니다. 프로그램이 중지됩니다. 완전히 실패했을 때 계속할 이유가 없습니다. 당신의 초의 예에서는 try catch가 중첩 된 것과 같습니다. 바깥 쪽 시도는 내부 catch의 예외를 catch합니다. 그러나 그 전에 마침내 호출됩니다. –

답변

2

표시되는 동작은 finally 블록 던지기와 관련이 없습니다. 당신은 단순히 응용 프로그램에서 처리되지 않은 예외가 그렇게되면 모든 베팅은 finally 블록 실행하거나하지 않은 경우를 포함하여, 꺼져 :

처리 된 예외 내에서 관련 finally 블록 :

MSDN 문서에서 실행이 보장됩니다. 그러나 예외가 처리되지 않은 경우 finally 블록의 실행은 예외 해제 작업이 트리거되는 방법에 따라 다릅니다. 이는 차례로 컴퓨터 설정 방법에 달려 있습니다. 자세한 내용은 CLR에서 처리되지 않은 예외 처리를 참조하십시오.

일반적으로 처리되지 않은 예외로 인해 응용 프로그램이 종료되면 finally 블록의 실행 여부가 중요하지 않습니다. 그러나 finally 블록에 해당 상황에서도 실행해야하는 문이있는 경우 try-finally 문에 catch 블록을 추가하는 것이 하나의 솔루션입니다.또는 호출 스택 위로 올라온 try-finally 문의 try 블록에서 throw 될 수있는 예외를 catch 할 수 있습니다. 즉, try-finally 문이 포함 된 메서드를 호출하는 메서드 나 해당 메서드를 호출하는 메서드 또는 호출 스택의 메서드에서 예외를 catch 할 수 있습니다. 예외가 포착되지 않으면 finally 블록의 실행은 운영 체제가 예외 unwind 작업을 트리거하도록 선택했는지 여부에 따라 다릅니다.

최종적으로 해야 실행을 차단하면

는, 그 해결책은 정확하게 두 번째 코드에서 한 일을하는 것입니다 : 처리되지 않은 예외를 처리합니다.

-1

What happens if a finally block throws an exception? :

C# 4 언어 사양 § 8.9.5 : 최종적 블록은 다른 예외가 발생하면, 현재의 예외 처리가 종료된다.

나는 마침내 블록은 깨끗한 리소스만을위한 것으로 생각하고 예외를 던져서는 안됩니다.

+0

이것은 어떤 방식 으로든 질문에 어떻게 대답합니까? – InBetween

관련 문제