基本上我听说某些条件会导致.net超越finally块。有谁知道这些条件是什么?
答案 0 :(得分:49)
两种可能性:
当存在StackOverflowException
时,不会执行finally块,因为堆栈上没有空间来执行更多代码。当ExecutionEngineException
出现Environment.FailFast()
时也不会调用它,这可能是因为调用{{1}}而产生的。
答案 1 :(得分:15)
除非CLR爆炸并且因ExecutingEngineException而崩溃(我在.net 1.1天中看到了一些只有适当数量的COM Interop :) ..我认为最终总是执行。
答案 2 :(得分:6)
你可以得到这样的情况:try块中的代码导致在输入try块之前抛出SecurityException(而不是在调用包含方法时抛出异常(参见http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx)),在此你永远不会进入try块的情况,所以finally块中的代码永远不会被调用。
其他可能性包括StackOverflowException和ExecutingEngineException。
答案 3 :(得分:4)
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");
}
}
}
。
_clone: function(obj){
let newObj = {};
for(let i in obj){
if(typeof(obj[i]) === 'object' && Object.keys(obj[i]).length){
newObj[i] = clone(obj[i]);
} else{
newObj[i] = obj[i];
}
}
return Object.assign({},newObj);
}
答案 4 :(得分:2)
还有Application.Exit方法。
答案 5 :(得分:0)
最后一个块之后的代码和外部作用域中的代码都不会先执行finally块而不执行finally块(finally块中的异常可能导致它过早退出,在这种情况下执行将从终结者到外部范围)。如果finally块之前的代码卡在无限循环或永不退出的方法中,或者执行上下文被完全销毁,则finally块将不会执行。
请注意,依赖finally块是合适的,不像“Finalize”方法(或C#“析构函数”),这些方法不应该被依赖。
答案 6 :(得分:0)
自从异步/等待以来,还有另一种可能最终被忽略的方法,而我在其他答案中没有提到过:
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();
}
}