Ответ 1
да это делает:-) http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
Возможный дубликат:
Будет ли код в объявлении Окончательный, если я верну его значение в блоке Try?
Рассмотрим следующий код кода С#. Выполняется ли блок "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. Однако, пожалуйста, не стесняйтесь отвечать!
да это делает:-) http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
Нет, нет. Он всегда будет выполняться при условии, что приложение все еще работает (за исключением исключения FastFail, Ссылка MSDN, как отмечали другие). Он будет выполняться, когда он выйдет из блока try/catch блока.
Он не будет выполняться, если приложение выйдет из строя: он будет убит с помощью команды процесса уничтожения и т.д. Это очень важно, потому что, если вы пишете код, который абсолютно ожидает его запуска, например, ручное откат, а если не другое он будет автоматически зафиксирован, вы можете запустить сценарий, который приложение прерывает до того, как это произойдет. Честно говоря, это внешний сценарий, но важно учитывать в этих ситуациях.
Из спецификации msdn С# инструкции try.
Операторы блока finally всегда выполняются, когда управление оставляет выражение о попытке. Это правда происходит ли передача управления как результат нормального исполнения, как результат выполнения перерыва, продолжение, goto или return, или как результат распространения исключения инструкции try. инструкции try.
Ссылка источника:
http://msdn.microsoft.com/en-us/library/aa664733(v=VS.71).aspx
Есть случаи, когда блок finally не будет выполняться.
Не совсем верно, что finally
всегда будет выполняться. См. этот ответ из Haacked:
Две возможности:
StackOverflowException
ExecutingEngineException
Блок finally не будет выполнен когда существует исключение StackOverflowException поскольку в стек нет места даже выполнить любой код. Это будет также не вызываться, когда есть ExecutingEngineException, которое очень редкий.
Фактически для любого вида асинхронного исключения (например, StackOverflowException
, OutOfMemoryException
, ThreadAbortException
) выполнение блока finally
не гарантируется.
Однако эти исключения являются исключениями, от которых обычно невозможно восстановить, и в большинстве случаев ваш процесс все равно выйдет.
На самом деле существует также, по крайней мере, еще один случай, когда finally
не выполняется, как описано Брайан Расмуссен в теперь удаленный вопрос:
В другом случае я знаю, что если Финализатор выдает исключение. В этом если процесс завершен сразу же, и, следовательно, гарантия не распространяется.
В приведенном ниже коде показана проблема
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 (ссылка С#)
Блок finally полезен для очистка любых ресурсов, выделенных в блок try, а также запуск любого код, который должен выполняться, даже если является исключением. Контроль всегда передано в блок finally как блок try выходит из.
Блок finally будет работать прямо между этими строками:
message = "You will not win!";
return;
Да, finally
всегда выполняется, теперь, будет ли код в блоке finally вызвать исключение - это другая история.
Да, при нормальных обстоятельствах (как указывали многие другие).
Блок finally полезен для очистка любых ресурсов, выделенных в блок try, а также запуск любого код, который должен выполняться, даже если является исключением. Контроль всегда передано в блок finally как выйдет блок try.
В то время как catch используется для обработки исключения, возникающие в заявлении блок, наконец, используется, чтобы гарантировать блок выполнения кода выполняется независимо от того, как предыдущая попытка блок завершен.
Правильный ответ: Да.
Попробуйте отладить вашу программу и поместите точку останова и посмотрите, как элемент управления все еще попадает в блок finally.
Нет, это не так.
Есть только один путь вокруг него, и это Environment.FailFast()
. См. http://msdn.microsoft.com/de-de/library/ms131100.aspx. В каждом другом случае гарантируется выполнение финализаторов; -)
Метод FailFast записывает сообщение строка в приложение Windows журнал событий создает свалку вашего приложения, а затем завершает текущий процесс. Строка сообщения также включаются в отчет об ошибках в Microsoft.
Используйте метод FailFast вместо Выйти из приложения, если состояние вашего приложение повреждено без ремонта, и выполнение вашего приложения try/finally блоки и финализаторы будут поврежденные ресурсы программы.
Простой ответ Да. Но в правиле есть некоторые "исключения".