在C#中,如果抛出未处理的exception,最终块将在try,catch中执行。

另一个面试问题是期待一个真/假答案,我不太确定。

重复

  • 在.NET中,如果catch块中的某些内容失败,最终总会被调用?
  • finally块总是运行吗?
  • 最终没有在.net中执行的条件try..finally阻止
  • 如果我在Try块中返回一个值,那么finally语句中的代码会触发吗?

finally大部分时间执行 。 这几乎是所有情况。 例如,如果在线程上抛出异步exception(如StackOverflowExceptionOutOfMemoryExceptionThreadAbortException ),则无法保证finally执行。 这就是存在用于编写高度可靠代码的约束执行区的原因。

对于面试目的,我希望这个问题的答案是错误的 (我不保证任何事情!面试官可能不知道这个!)。

通常, finally块可以保证执行。

但是,少数情况会在发生错误时强制CLR关闭。 在这些情况下, finally块不会运行。

一个这样的例子是存在StackOverflowexception。

例如,在下面的代码中,不执行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); } 

我知道的另一种情况是终结器抛出exception。 在这种情况下,该过程也会立即终止,因此保证不适用。

下面的代码说明了这个问题

 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(); } } 

在这两种情况下,该过程在catchfinally之前终止。

我承认这些例子非常人为,但它们只是为了说明这一点。

幸运的是,两者都不经常发生。

直接来自MSDN:

finally块对于清理try块中分配的任何资源非常有用。 无论try块如何退出,控制总是传递给finally块。

catch用于处理语句块中发生的exception,而最终用于保证语句代码块的执行,而不管前面的try块是如何退出的。

http://msdn.microsoft.com/en-us/library/zwc8s4fz(VS.71,loband).aspx

是的,最后总是执行。

最终将永远执行并不完全正确。 看到Haacked的 回答 :

两种可能性:

  • StackOverflowException
  • ExecutingEngineException

当存在StackOverflowException时,不会执行finally块,因为堆栈上没有空间来执行任何更多的代码。 当存在ExecutingEngineException时,它也不会被调用,这是非常罕见的。

但是,这两个例外情况是您无法恢复的exception,所以基本上您的进程无论如何都会退出。

正如Mehrdad所提到的,可靠的try / catch /最终将不得不使用约束执行区(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; } } 

通常,无论是否抛出exception以及是否处理任何exception,始终执行finally块。

有几个例外(有关详细信息,请参阅其他答案)。

无论是否抛出exception,都会执行’finally’。

它是关闭任何开放连接的好地方。 执行成功或失败,您仍然可以管理连接或打开文件。

最后,每次尝试catch块都会发生

最后,无论如何都保证执行块。

最后总是执行。 我不依赖于try块的工作原理。 如果你必须为try和cath做一些额外的工作,最好放入finally块。 所以你可以保证它总是被执行。