진실 / 거짓 대답을 기대하고 있었고 나는 너무 확신하지 못했다는 또 다른 인터뷰 질문.
finally
실행 됨대부분의 시간. 거의 모든 경우입니다. 예를 들어 비동기 예외 (예 :StackOverflowException
,OutOfMemoryException
,ThreadAbortException
) 스레드에서 throw됩니다.finally
실행은 보장되지 않습니다. 이는 이유제한된 실행 영역신뢰성이 높은 코드를 작성하기 위해 존재합니다.
인터뷰 목적으로이 질문에 대한 대답은그릇된(나는 아무것도 보증하지 않을 것입니다! 면접관은이 자신을 알지 못할 수도 있습니다!).
일반적으로finally
블록의 실행이 보장됩니다.
그러나 몇 가지 경우에 오류가 발생하면 CLR을 강제 종료합니다. 이 경우,finally
블록이 실행되지 않습니다.
하나의 예제는 StackOverflow 예외가있는 상태입니다.
예 : 아래의 코드에서finally
블록이 실행되지 않습니다.
static void Main(string[] args) {
try {
Foo(1);
} catch {
Console.WriteLine("catch");
} finally {
Console.WriteLine("finally");
}
}
public static int Foo(int i) {
return Foo(i + 1);
}
내가 아는 또 다른 경우는 마무리자가 예외를 throw하는 경우입니다. 이 경우 프로세스가 즉시 종료되므로 보증이 적용되지 않습니다.
아래 코드는 문제를 보여줍니다.
static void Main(string[] args) {
try {
DisposableType d = new DisposableType();
d.Dispose();
d = null;
GC.Collect();
GC.WaitForPendingFinalizers();
} catch {
Console.WriteLine("catch");
} finally {
Console.WriteLine("finally");
}
}
public class DisposableType : IDisposable {
public void Dispose() {
}
~DisposableType() {
throw new NotImplementedException();
}
}
두 경우 모두 프로세스가 종료되기 전에catch
과finally
.
예제가 매우 고안된 것을 인정하지만, 그 예제를 설명하기 위해 만들어졌습니다.
다행히도 어느 누구도 자주 일어나지 않습니다.
MSDN에서 직접 스트리밍 :
finally 블록은 다음에 유용합니다. 할당 된 자원 정리 try 블록. 컨트롤은 항상 finally 블록에 관계없이 전달됨 try 블록의 종료 방법에 대한 설명입니다.
catch는 처리하는 데 사용되는 반면 명령문에서 발생하는 예외 블록, 마지막으로 명령문 블록 실행 이전 시도 방법에 관계없이 블록이 종료되었습니다.
http://msdn.microsoft.com/en-us/library/zwc8s4fz(VS.71,loband).aspx
예, 마침내 항상 실행됩니다.
마침내 항상 처형 될 것이라는 것은 완전히 사실이 아닙니다. 만나다이 대답...에서해킹 된:
두 가지 가능성 :
StackOverflowException
ExecutingEngineException
finally 블록은 실행되지 않습니다. StackOverflowException이있을 때 스택에 아무 공간도 없기 때문에 더 이상 코드를 실행할 수 없습니다. 그것은 거기있을 때도 전화하지 마세요. ExecutingEngineException은 다음과 같습니다. 매우 드물다.
그러나이 두 가지 예외는 복구 할 수없는 예외이므로 기본적으로 프로세스는 종료됩니다.
Mehrdad가 말했듯이, 신뢰할 수있는 try / catch / finally는제한된 실행 영역 (CER). 안예MSDN에서 제공합니다.
[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
public IntPtr m_outputHandle;
}
sealed class MySafeHandle : SafeHandle
{
// Called by P/Invoke when returning SafeHandles
public MySafeHandle()
: base(IntPtr.Zero, true)
{
}
public MySafeHandle AllocateHandle()
{
// Allocate SafeHandle first to avoid failure later.
MySafeHandle sh = new MySafeHandle();
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
MyStruct myStruct = new MyStruct();
NativeAllocateHandle(ref myStruct);
sh.SetHandle(myStruct.m_outputHandle);
}
return sh;
}
}
일반적으로 finally 블록은 예외가 발생했는지 여부와 예외가 처리되었는지 여부에 관계없이 항상 실행됩니다.
두 가지 예외가 있습니다 (자세한 내용은 다른 답변을 참조하십시오).
'Finally'는 예외가 throw되는지 여부에 관계없이 실행됩니다.
열려있는 연결을 닫을 수있는 좋은 장소입니다. 성공 또는 실패한 실행은 여전히 연결을 관리하거나 파일을 열 수 있습니다.
마지막으로 catch 블록을 시도 할 때마다 발생합니다.
마지막으로 블록은 어떤 경우에도 실행되도록 보장됩니다.
마지막으로 항상 실행됩니다. try 블록이 어떻게 작동하는지에 달려 있지 않습니다. try와 cath 모두에 대해 몇 가지 추가 작업을해야한다면 finally 블록을 넣는 것이 좋습니다. 그래서 당신은 항상 그것을 처형 할 수 있습니다.