Существуют ли ситуации, когда целесообразно использовать блок try-finally
без блока catch
?
Используйте блок "try-finally" без блока "catch"
Ответ 1
Вы использовали бы его для обеспечения выполнения некоторых действий после содержимого try
или исключения, но если вы не хотите использовать это исключение.
Чтобы быть ясным, это не скрывает исключений. Блок finally
запускается до того, как исключение будет распространено в стеке вызовов.
Вы также случайно использовали бы его, когда используете ключевое слово using
, потому что оно компилируется в try-finally
(а не точное преобразование, но для аргумента оно достаточно близко).
try
{
TrySomeCodeThatMightException();
}
finally
{
CleanupEvenOnFailure();
}
Не запускается код, выполняющийся в finally
, но случай, когда он не гарантируется, является довольно красным - я даже не могу его запомнить. Все, что я помню, если вы в этом случае, то очень хорошие шансы, что не запускать finally
не самая большая проблема:-), так что в основном не потеть.
Обновление от Tobias: finally
не будет запущено, если процесс будет убит.
Обновление от Paddy: Условия, когда, наконец, не выполняются в блоке .net try..finally
Наиболее распространенным примером, который вы можете увидеть, является удаление соединения с базой данных или внешнего ресурса, даже если код не работает:
using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
// Do stuff.
}
Скомпилируется во что-то вроде:
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}
Ответ 2
using
эквивалентен try-finally
. Вы будете использовать try-finally
только в том случае, если хотите сделать некоторую очистку внутри finally
и не заботятся об исключении.
лучший подход будет
try
{
using(resource)
{
//Do something here
}
}catch(Exception)
{
//Handle Error
}
При этом даже очистка, вызванная using
, не будет выполнена, ваш код не будет работать.
Есть некоторые условия, когда finally
не будет выполняться.
- Если есть
StackOverflowException
илиExecutingEngineException
. - Процесс уничтожается из внешнего источника.
Надеюсь, это ответит на ваши сомнения.
Ответ 3
Если у вас есть, например, неуправляемый ресурс, который вы создаете и используете в блоке try, вы можете использовать блок finally, чтобы обеспечить освобождение этого ресурса. Блок finally всегда будет выполнен, несмотря на то, что происходит (например, исключения) в блоке try.
например. инструкция lock (x) действительно:
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
Блок finally всегда вызывается для обеспечения освобождения исключительной блокировки.
Ответ 4
Хорошее объяснение с использованием кода:
void MyMethod1()
{
try
{
MyMethod2();
MyMethod3();
}
catch(Exception e)
{
//do something with the exception
}
}
void MyMethod2()
{
try
{
//perform actions that need cleaning up
}
finally
{
//clean up
}
}
void MyMethod3()
{
//do something
}
Если MyMethod2 или MyMethod3 выдает исключение, он будет пойман MyMethod1. Тем не менее, код в MyMethod2 должен запускать очищающий код, например. закрывая соединение с базой данных, перед тем как исключение будет передано в MyMethod1.
Ответ 5
Вам нужен блок finally, когда независимо от того, какие (если есть) исключения были пойманы или даже если никто не пойман, вы все равно хотите выполнить некоторый код до выхода блока. Например, вы можете закрыть открытый файл.
См. также try-finally
Ответ 6
try/finally: когда вы не хотите обрабатывать какие-либо исключения, но хотите, чтобы выполнялось какое-либо действие независимо от того, выбрано ли исключение вызываемым кодом.
Ответ 7
Посмотрите на следующую ссылку: https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause
Это зависит от архитектуры вашего приложения и операции, выполняемой вами в блоке.
Ответ 8
Вот ситуация, когда вы, возможно, захотите использовать try finally: когда вы обычно используете оператор using, но не можете, потому что вы вызываете метод путем отражения.
Это не сработает
using (objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{
}
вместо этого используйте
object objMsg = null;
try
{
objMsg
= Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));
strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
| BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
new object[] { vxmlRequest.OuterXml });
}
finally
{
if (objMsg!=null)
((IDisposable)objMsg).Dispose();
}
Ответ 9
Я ничего не знаю о С#, но кажется, что все, что вы могли бы сделать с помощью try-finally, вы могли бы более элегантно сделать с помощью инструкции . С++ даже не имеет в итоге результат его RAII.
Ответ 10
Здесь используется прецедент, который я всегда (uhm..) использует:
int? x; //note the nullable type here!
try
{
x = int.Parse(someString);
}
catch { } //don't care, let it just be null
Ответ 11
1. Мы можем использовать блок try без catch, но мы должны использовать catch/finally, любой из них. 2.Мы не можем использовать только блок try.