Does the C# “finally” block ALWAYS execute?
Possible Duplicate:
Will code in a Finally statement fire if I return a value in a Try block?
考虑以下代码C代码。"finally"块是否执行?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public void DoesThisExecute() { string ext ="xlsx"; string message = string.Empty; try { switch (ext) { case"xls": message ="Great choice!"; break; case"csv": message ="Better choice!"; break; case"exe": message ="Do not try to break me!"; break; default: message ="You will not win!"; return; } } catch (Exception) { // Handle an exception. } finally { MessageBox.Show(message); } } |
哈,写完这篇文章后,我意识到我可以自己在Visual Studio中测试这篇文章。不过,请随时回答!
不,不是。如果应用程序仍在运行,它将始终执行(除非在fastfail异常、msdn链接期间,如其他人指出的那样)。它将在退出块的Try/Catch部分时执行。
如果应用程序崩溃,它将不会执行:通过kill process命令等被杀死。这是非常重要的,因为如果编写的代码绝对希望它运行,例如手动执行回滚,如果不是其他方式,它将自动提交,您可以运行到e应用程序在这之前中止。老实说,这是一个外部场景,但在这些情况下需要注意这一点很重要。
根据
The statements of a
finally block are always executed when control leaves atry statement. This is true whether the control transfer occurs as a result of normal execution, as a result of executing abreak ,continue ,goto , orreturn statement, or as a result of propagating an exception out of thetry statement.
来源
在某些情况下,finally块将不执行:
执行
Two possibilities:
StackOverflowException ExecutingEngineException The finally block will not be executed
when there's a StackOverflowException
since there's no room on the stack to
even execute any more code. It will
also not be called when there's an
ExecutingEngineException, which is
very rare.
事实上,对于任何类型的异步异常(如
但是,这些异常是您通常无法恢复的异常,在大多数情况下,您的进程将退出。
事实上,还有至少一种情况是,在现已删除的问题中,没有按照Brian Rasmussen的描述执行
The other case I am aware of is if a
finalizer throws an exception. In that
case the process is terminated
immediately as well, and thus the
guarantee doesn't apply.The code below illustrates the problem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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(); } } |
可靠的try/catch/finally必须使用受约束的执行区域(cer)。MSDN提供了一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [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; } } |
以下文章是一个很好的信息来源:
Reliability Best Practices
是的,它有:-)http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
来自msdn try finally(C参考)
The finally block is useful for
cleaning up any resources allocated in
the try block as well as running any
code that must execute even if there
is an exception. Control is always
passed to the finally block regardless
of how the try block exits.
最后一个块将在这些行之间运行:
1 2 | message ="You will not win!"; return; |
是的,在正常情况下(正如许多其他人指出的那样)。
The finally block is useful for
cleaning up any resources allocated in
the try block as well as running any
code that must execute even if there
is an exception. Control is always
passed to the finally block regardless
of how the try block exits.Whereas catch is used to handle
exceptions that occur in a statement
block, finally is used to guarantee a
statement block of code executes
regardless of how the preceding try
block is exited.
http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
不,它没有。
但只有一条路可以绕过它,那就是
The FailFast method writes the message
string to the Windows Application
event log, creates a dump of your
application, and then terminates the
current process. The message string is
also included in error reporting to
Microsoft.Use the FailFast method instead of the
Exit method to terminate your
application if the state of your
application is damaged beyond repair,
and executing your application's
try/finally blocks and finalizers will
corrupt program resources.
正确的答案是肯定的。
尝试调试您的程序并放置一个断点,然后观察控件是否仍命中最后一个块。
是的,
简单回答是。但这条规则也有一些"例外"。