Всегда ли выполняется блок C# "finally"? [дубликат]
Возможные Дубликаты:
будет ли код в конечном счете срабатывать, если я возвращаю значение в блоке Try?
рассмотрим следующий код на C#. Выполняется ли блок" finally"?
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. Однако, пожалуйста, не стесняйтесь отвечать!
11 ответов:
да это так : -)http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
нет это не так. Он всегда будет выполняться при условии, что приложение все еще работает (за исключениемFastFail исключения MSDN link, как и другие отметили). Он будет выполняться при выходе из части try / catch блока.
Он не будет выполняться, если приложение аварийно завершает работу: убивается через команду процесса убийства и т. д. Это очень важно, потому что если вы пишете код, который абсолютно ожидает его запуска, например, вручную выполнить откат, и если это не будет автоматически зафиксировано, вы можете запустить сценарий, который приложение прерывает, прежде чем это произойдет. Честно говоря, это внешний сценарий, но важно принять к сведению в этих ситуациях.
из спецификации MSDN C#
try
о себе:заявления
finally
блок всегда выполняется, когда элемент управления покидает atry
заявление. Это верно, если передача управления происходит в результате нормального выполнения, в результате выполненияbreak
,continue
,goto
илиreturn
оператор, или в результате распространения исключения изtry
заявление.бывают случаи, когда блок finally не будет выполняться:
- окружающая среда.Содержащие
- Неуловимые типы исключений
- Сбой Питания
это не совсем верно, что
finally
всегда будет выполняться. Смотрите ответ С Haacked:два варианта:
StackOverflowException
ExecutingEngineException
блок finally не будет выполнен когда есть исключение StackOverflowException так как нет места в стеке даже выполнить любой другой код. Оно будет также не будет называться, когда есть ExecutingEngineException, который является очень редко.
фактически, для любого вида асинхронного исключения (например
StackOverflowException
,OutOfMemoryException
,ThreadAbortException
) исполнение afinally
блока не гарантируется.однако эти исключения являются исключениями, которые вы обычно не можете восстановить, и в большинстве случаев ваш процесс все равно завершится.
в самом деле, есть также по крайней мере один случай, когда
finally
не выполняется, как описано Брайан Расмуссен в настоящее время удаленный вопрос:другой случай, о котором я знаю, если a финализатор создает исключение. В том случае процесс прекращается сразу же, а значит и гарантия не распространяется.
приведенный ниже код иллюстрирует проблему
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 / наконец-то придется использовать ограниченные области выполнения (CER). Один пример обеспечивается MSDN:
[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; } }
отличным источником информации является следующая статья:
от MSDN try-finally (ссылка на C#)
блок finally полезен для очистка любых ресурсов, выделенных в блок try, а также запуск любого код, который должен выполняться, даже если есть являться исключением. управление всегда передано в блок finally независимо о том, как блок try выходит.
да
finally
всегда выполняется, теперь независимо от того, вызовет ли код в блоке finally исключение, это другая история.
правильный ответ-да.
попробуйте отладить свою программу и поставить точку останова и смотреть, как контроль все еще попадает в блок finally.
нет это не так.
есть только один способ обойти это, хотя и это
Environment.FailFast()
. См.http://msdn.microsoft.com/de-de/library/ms131100.aspx. в любом другом случае гарантируется выполнение финализаторов ;-)метод FailFast записывает сообщение строка для приложения Windows журнал событий, создает дамп применение, и после этого прекращает текущий процесс. Строка сообщения является также включены в ошибку отчетность Microsoft.
используйте метод FailFast вместо Метод выхода для завершения работы применение если государство вашего приложение повреждено и не подлежит ремонту, и выполнение вашего приложения попробуйте / наконец блоки и финализаторы будут коррумпированные ресурсы программы.
да, при нормальных обстоятельствах (как указывали многие другие).
блок finally полезен для очистка любых ресурсов, выделенных в блок try, а также запуск любого код, который должен выполняться, даже если есть являться исключением. Контроль есть всегда передано в блок finally независимо о том, как блок try выходит.
в то время как catch используется для обработки исключения, возникающие в инструкции блок, наконец, используется, чтобы гарантировать блок инструкций кода выполняется независимо от того, как предыдущая попытка блок выходит.