基本的に、特定の条件によって .net が finally ブロックを通過してしまうと聞いたことがあります。それらの条件を知っている人はいますか?
7 に答える
2 つの可能性:
StackOverflowException
スタックにはこれ以上コードを実行する余地がないため、finally ブロックは実行されません。ExecutionEngineException
への呼び出しから発生する可能性のある がある場合にも呼び出されませんEnvironment.FailFast()
。
CLRが爆発してExecutingEngineExceptionでダウンしない限り(.net 1.1で、適切な量のCOM相互運用性を備えた日をいくつか見ました:) ..最終的には常に実行する必要があると思います。
try ブロック内のコードが原因で、try ブロックに入る前に SecurityException がスローされる状況が発生する可能性があります (代わりに、含まれているメソッドが呼び出されたときに例外がスローされます ( http://msdn.microsoft.com/en-usを参照)。 /library/fk6t46tz(VS.71).aspx ))、この状況では、try ブロックに入ることさえないため、finally ブロックのコードが呼び出されることはありません。
その他の可能性としては、StackOverflowException や ExecutingEngineException などがあります。
Finally
block onbackground 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 ブロックは実行されません。
適切に依存すべきではない "Finalize" メソッド (または C# の "デストラクタ") とは異なり、finally ブロックに依存することが適切であることに注意してください。
async/await 以来、他の回答で言及されていない、最終的に無視される可能性のある別の方法があります。
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();
}
}