try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
위의 블록에서 finally 블록은 언제 호출됩니까? e를 던지기 전에 또는 마지막으로 부름을 받아 붙잡는가?
답변
e가 다시 던져진 후 (즉, catch 블록이 실행 된 후) 호출됩니다.
이 7 년 후 편집 – 한 가지 중요한 점은 e
try / catch 블록에 의해 호출 스택을 더 이상 잡지 않거나 전역 예외 처리기에 의해 처리 되지 않으면 finally
블록 이 전혀 실행될 수 없다는 것입니다.
답변
시도해 보지 않겠습니까?
outer try
inner try
inner catch
inner finally
outer catch
outer finally
코드 포함 (수직 공간 용) :
static void Main() {
try {
Console.WriteLine("outer try");
DoIt();
} catch {
Console.WriteLine("outer catch");
// swallow
} finally {
Console.WriteLine("outer finally");
}
}
static void DoIt() {
try {
Console.WriteLine("inner try");
int i = 0;
Console.WriteLine(12 / i); // oops
} catch (Exception e) {
Console.WriteLine("inner catch");
throw e; // or "throw", or "throw anything"
} finally {
Console.WriteLine("inner finally");
}
}
답변
최종 대답은 같이 여기에 대한 답변을 모두 읽은 후에는 보이는 것이 달려있다 :
-
catch 블록 내에서 예외를 다시 발생시키고 해당 예외가 다른 catch 블록 내에서 포착되면 모든 것이 문서에 따라 실행됩니다.
-
그러나 다시 자르기 예외가 처리되지 않으면 최종 실행은 절대 실행되지 않습니다.
이 코드 샘플을 VS2010 w / C # 4.0에서 테스트했습니다.
static void Main()
{
Console.WriteLine("Example 1: re-throw inside of another try block:");
try
{
Console.WriteLine("--outer try");
try
{
Console.WriteLine("----inner try");
throw new Exception();
}
catch
{
Console.WriteLine("----inner catch");
throw;
}
finally
{
Console.WriteLine("----inner finally");
}
}
catch
{
Console.WriteLine("--outer catch");
// swallow
}
finally
{
Console.WriteLine("--outer finally");
}
Console.WriteLine("Huzzah!");
Console.WriteLine();
Console.WriteLine("Example 2: re-throw outside of another try block:");
try
{
Console.WriteLine("--try");
throw new Exception();
}
catch
{
Console.WriteLine("--catch");
throw;
}
finally
{
Console.WriteLine("--finally");
}
Console.ReadLine();
}
출력은 다음과 같습니다.
예 1 : 다른 try 블록 내부에서 다시 던지기 :
–outer try
—- inner try
—- inner catch
—- inner finally
–outer catch
–outer finally
Huzzah!예 2 : 다른 try 블록 외부에서 다시 던지기 :
–try
–catch처리되지 않은 예외 : System.Exception : ‘System.Exception’유형의 예외가 발생했습니다.
C : \ local source \ ConsoleApplication1 \ Program.cs : line의 ConsoleApplication1.Program.Main ()에서 53
답변
귀하의 예는 다음 코드와 동일하게 작동합니다.
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
부수적으로, 실제로 의미하는 경우 throw e;
(즉, 방금 잡은 것과 동일한 예외를 던짐) 새 스택을 만드는 대신 원래 스택 추적을 유지하기 때문에 수행 하는 것이 훨씬 좋습니다 throw;
.
답변
catch 처리기 블록 내에 처리되지 않은 예외가 있으면 finally 블록이 정확히 0 번 호출됩니다.
static void Main(string[] args)
{
try
{
Console.WriteLine("in the try");
int d = 0;
int k = 0 / d;
}
catch (Exception e)
{
Console.WriteLine("in the catch");
throw;
}
finally
{
Console.WriteLine("In the finally");
}
}
산출:
C : \ users \ administrator \ documents \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
시도에서
캐치
처리되지 않은 예외 : System.DivideByZeroException : 0으로 나누려고했습니다. C : \ users \ administrator \ documents \ TestExceptionNesting \ TestExceptionNesting.cs : line의 TestExceptionNesting.Program.Main (String [] args)에서 22 행
C : \ users \ administrator \ documents \ TestExceptionNesting \ bin \ release>
나는 오늘 인터뷰에서이 질문을 받았고 인터뷰자는 계속해서 “마지막으로 불려지지 않습니까?” 그것이 트릭 질문인지 아니면 면접관이 다른 것을 염두에두고 디버깅하기 위해 잘못된 코드를 작성했는지 확실하지 않았으므로 집에 와서 시도해 보았습니다 (디버거 상호 작용 없음). 쉬다.
답변
간단한 방법은 코드를 디버깅하고 마지막으로 호출 될 때 알림을받는 것입니다.
답변
C # 콘솔 응용 프로그램을 사용한 테스트에서 예외가 발생한 후 최종 코드가 실행되었습니다. “응용 프로그램 오류 대화 상자”가 존재하고 “프로그램 닫기”옵션을 선택한 후 finally 블록이 해당 콘솔 창에서 실행되었습니다. 그러나 finally 코드 블록 안에 중단 점을 설정하면 절대로 칠 수 없습니다. 디버거는 throw 문에서 계속 중지합니다. 내 테스트 코드는 다음과 같습니다.
class Program
{
static void Main(string[] args)
{
string msg;
Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
}
static int GetRandomNumber(out string errorMessage)
{
int result = 0;
try
{
errorMessage = "";
int test = 0;
result = 3/test;
return result;
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw ex;
}
finally
{
Console.WriteLine("finally block!");
}
}
}
VS2010에서 디버깅-.NET Framework 4.0