Условия, когда finally не выполняется при блокировке .net try..finally
-
02-07-2019 - |
Вопрос
В принципе, я слышал, что определенные условия приведут к тому, что .net пропустит блок finally.Кто-нибудь знает, что это за условия?
Решение
Две возможности:
Блок finally не будет выполнен, когда будет StackOverflowException
поскольку в стеке нет места даже для выполнения какого-либо другого кода.Он также не будет вызван, когда есть ExecutionEngineException
, которые могут возникнуть в результате вызова Environment.FailFast()
.
Другие советы
Если только среда CLR не взорвется и не выйдет из строя с ExecutingEngineException (я видел несколько за дни .net 1.1 с нужным количеством COM-взаимодействия :) ..Я думаю, наконец-то следует всегда казнить.
Вы можете получить ситуацию, когда код в блоке try вызывает исключение SecurityException, вызываемое до ввода блока try (вместо этого исключение генерируется при вызове содержащего метода (см. http://msdn.microsoft.com/en-us/library/fk6t46tz (ПРОТИВ 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");
}
}
}
Существует также приложение.Метод выхода.
Ни код, следующий за блоком finally, ни код во внешних областях, не будут выполняться без предварительного запуска блока finally (исключение внутри блока finally может привести к преждевременному завершению, и в этом случае выполнение переместится из финализатора во внешнюю область).Если код, предшествующий блоку finally, застревает в бесконечном цикле или методе, который никогда не завершается, или если контекст выполнения полностью уничтожен, блок finally выполняться не будет.
Обратите внимание, что правильно полагаться на блоки finally, в отличие от методов "Finalize" (или "деструкторов" C #), на которые не следует полагаться должным образом.