基本上我听说某些条件会导致 .net 吹过 finally 块。有谁知道这些条件是什么?
7 回答
除非 CLR 因 ExecutingEngineException 而崩溃并崩溃(我在 .net 1.1 中看到过一些只有适量的 COM Interop :) .. 我认为 finally 应该始终执行。
您可能会遇到这样的情况:try 块中的代码导致在进入 try 块之前引发 SecurityException(而不是在调用包含方法时引发异常(请参阅http://msdn.microsoft.com/en-us /library/fk6t46tz(VS.71).aspx )),在这种情况下,您甚至永远不会进入 try 块,因此永远不会调用 finally 块中的代码。
其他可能性包括 StackOverflowException 和 ExecutingEngineException。
Finally
阻止background thread
可能无法执行。但是,这取决于甚至在完全执行之前main foreground thread
终止background thread
操作的完成执行background thread
。
class Program
{
static void Main(string[] args)
{
Program prgm = new Program();
Thread backgroundThread = new Thread(prgm.CheckBgThread);
backgroundThread.IsBackground = true;
backgroundThread.Start();
Console.WriteLine("Closing the program....");
}
void CheckBgThread()
{
try
{
Console.WriteLine("Doing some work...");
Thread.Sleep(500);
}
finally
{
Console.WriteLine("This should be always executed");
}
}
}
还有 Application.Exit 方法。
finally 块之后的代码和外部范围内的代码都不会在 finally 块首先启动的情况下执行(finally 块中的异常可能导致它过早退出,在这种情况下,执行将从终结器跳到外部范围)。如果 finally 块之前的代码陷入无限循环或永远不会退出的方法,或者如果执行上下文被完全销毁,finally 块将不会执行。
请注意,依赖 finally 块是正确的,这与不应正确依赖的“Finalize”方法(或 C#“析构函数”)不同。
由于 async/await,还有另一种方法 finally 可能会被忽略,这是我在其他答案中没有提到的:
static class Program
{
[STAThread]
static void Main()
{
async void ThreadExecutionAsync()
{
try
{
SynchronizationContext.SetSynchronizationContext(
new WindowsFormsSynchronizationContext());
await Task.Yield(); // Yield to the context
// The WindowsFormsSynchronizationContext will schedule the continuation
// on the main thread, so the current thread will die
// and we will never get here...
Debugger.Break();
}
finally
{
// Will never get here either...
Debugger.Break();
}
}
var thread = new Thread(ThreadExecutionAsync);
thread.Start();
Application.Run();
}
}