2009-10-16 3 views
17

예외 처리 : throw 된 후에 마침내 실행됩니까?

다음 코드가 있다고 가정하십시오.

다음을 수행하는 대신

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 

    ' 
    ' Clean up-code that gets not reached because exception 
    ' 
Catch e As Exception 
    ' 
    'Clean up initialized objects 
    ' 

    Throw e 
End Try 

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception 
    Throw e 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

그래서 간단한 질문입니다. 전에 몇 줄을 던져도 블록에 도달 했습니까?

[편집] 빠른 답변 주셔서 감사합니다.

첫 번째 줄에는 NullReference-, COM- 및 FileNotFound-Exceptions이 있습니다.

좋아,이 코드를 위해 갈 것이다 :

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception  ' or just "Catch"??   
    Throw 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

모두 최고!

이노

+2

'쓰레기'라고 쓰지 말고 그냥 버려야합니다. 그렇지 않으면 예외 스택 추적을 재설정하므로 예외가 처음 발생한 위치에 대한 정보가 손실됩니다. –

답변

25

그래서 내 간단한 질문입니다 : 예외의 경우는 마지막 몇 줄 앞에 던져이 경우에도 도달 블록에서?

예. Finally block이고 항상입니다.은 정확히 정리를 위해 존재하며 정확하게 존재합니다. 코드에서 Catch 블록을 제거하십시오. 아무 것도 수행하지 않습니다. 더 나쁜 것은 원래의 예외를 다시 던지지 않기 때문에 스택 추적을 실제로 파기합니다. 새 예외를 throw합니다.

Catch e As XyzException 
    ' … do some stuff. ' 
    Throw 
End Try 

1) : 당신이 정말로 그때 다시 발생 예외를 Catch 블록을해야하는 경우

다음을 사용 emptor 경고 : 같은 StackOverflowException 같은 일부 예외 (방법이 있습니다 피팅 ...) 특별한주의가 필요하며 Finally 블록을 트리거하지 않을 수 있습니다. 올바르게 처리하는 것은 대개 매우 어렵습니다.

+1

Konrad - 마지막으로 항상 실행되는 것은 아닙니다. 예를 들어 OutOfMemoryException이있을 때 실행되지 않습니다. –

+0

@ Pete : 맞아.하지만 이것들은 특정한 엣지 케이스 야. –

+1

@ Pete : StackOverflowException을 의미하지 않습니까? OutOfMemoryException의 경우에 마침내 실행되는 테스트를 쉽게 수행 할 수 있습니다. –

0

예, 결국 어떤 경우에도 실행됩니다. (단지 몇 가지 예외가 있습니다 - Response.Redirect 및 멀티 스레딩을 사용하는 일부 경우)

5

아니요, 실행하지 않을 수 없습니다. 예를 들어 StockOverflowException 및 OutOfMemoryException과 같은 특정 예외가 있습니다. finally 블록의 실행이 보장되지 않는 경우입니다.

1

거의 모든 경우에 Finally는 Try/Catch 블록에서 실행됩니다 (StackOverflowException 또는 OutOfMemoryException 발생시를 포함하여 주목할만한 예외 사항). 나는 호기심이지만, 왜 너 자신을 위해 이것을 시도하지 않았는가. 사물을 배우는 귀중한 방법은 실제로 스스로를 시험해 보는 것입니다. 어쨌든 당신은 잘못되거나 오도 된 대답을 받아 들일 수 있습니다. 그러면 그 시점부터이 거짓을 가지고 일하게 될 것입니다.

+1

나는 이것을 시험해 보았지만 나의 디버거는 던지기를 멈췄다. 나는 문서를 읽고 내 질문에 대한 힌트를 찾지 못했습니다. 나는이 질문을 내 질문에 직접적으로 속하게하고 간접적으로 그것에 속하는 답을 얻도록 요청했다. ("마침내 특별한 상황이 실행되지 않는다"와 같은 힌트와 같이). – Inno

1

참고 : System.Environment.FastFail 메서드는 finally 섹션을 실행하지 않고 현재 프로세스/스레드 immediatly를 종료했습니다.