Используйте блок try-finally без блока catch - PullRequest
63 голосов
/ 15 февраля 2012

Существуют ли ситуации, когда целесообразно использовать блок try-finally без блока catch?

Ответы [ 11 ]

98 голосов
/ 15 февраля 2012

Вы могли бы использовать его, чтобы обеспечить выполнение некоторых действий после содержимого try или исключения, но если вы не хотите использовать это исключение.

Просто чтобы прояснить, это не скрывает исключений. Блок finally запускается до того, как исключение распространяется по стеку вызовов.

Вы также можете непреднамеренно использовать его при использовании ключевого слова using, поскольку оно компилируется в try-finally (не точное преобразование, но для аргумента оно достаточно близко).

try
{
    TrySomeCodeThatMightException();
}
finally
{
    CleanupEvenOnFailure();
}

Код, выполняемый в finally, не гарантированно выполняется, однако случай, когда он не гарантирован, является довольно краевым - я даже не могу вспомнить это. Все, что я помню, это то, что если вы в этом случае, очень велики шансы, что не запускать finally не является вашей самой большой проблемой :-), так что в основном не переживайте.

Обновление от Тобиаса: finally не запустится, если процесс будет остановлен.

Обновление от Paddy: Условия, когда, наконец, не выполняется в .net try..finally block

Наиболее распространенный пример, который вы можете увидеть, это удаление соединения с базой данных или внешнего ресурса, даже если код завершится ошибкой:

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();
}
5 голосов
/ 15 февраля 2012

using эквивалентно try-finally. Вы будете использовать try-finally только тогда, когда захотите провести некоторую очистку внутри finally и не будете беспокоиться об исключении.

лучший подход будет

try
{
   using(resource)
   {
       //Do something here
   }   
}catch(Exception)
{
     //Handle Error
}

Если даже выполнить очистку, вызванную using, не удастся, ваш код не потерпит неудачу.

Есть некоторые условия, когда finally не будет выполнен.

  • Если есть какие-либо StackOverflowException или ExecutingEngineException.
  • Процесс убит из внешнего источника.

Надеюсь, это ответит на ваши сомнения.

3 голосов
/ 15 февраля 2012

Если у вас есть, например, неуправляемый ресурс, который вы создаете и используете в блоке try, вы можете использовать блок finally, чтобы обеспечить освобождение этого ресурса. Блок finally всегда выполняется, несмотря на то, что происходит (например, с исключениями) в блоке try.

например. оператор lock (x) действительно:

System.Threading.Monitor.Enter(x); 
try { ... } 
finally 
{ 
    System.Threading.Monitor.Exit(x); 
} 

Блок finally всегда вызывается для обеспечения снятия эксклюзивной блокировки.

2 голосов
/ 16 апреля 2015

Хорошее объяснение с использованием кода:

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.

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+

1 голос
/ 15 сентября 2015

Вот ситуация, когда вы, возможно, захотите использовать try finally: когда вы обычно используете оператор using, но не можете, потому что вы вызываете метод с помощью отражения.

Это не сработает *Вместо 1003 *

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();
            }
1 голос
/ 15 февраля 2012

Посмотрите на следующую ссылку: https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause

Это зависит от архитектуры вашего приложения и операции, которую вы выполняете в блоке.

1 голос
/ 15 февраля 2012

try / finally: когда вы не хотите обрабатывать какие-либо исключения, но хотите обеспечить выполнение некоторых действий независимо от того, было ли вызвано исключение вызванным кодом или нет.

1 голос
/ 15 февраля 2012

Вам нужен блок finally, когда независимо от того, какие (если таковые имеются) исключения были перехвачены или даже если ни одно не перехвачено, вы все равно хотите выполнить некоторый код до выхода из блока. Например, вы можете закрыть открытый файл.

См. Также try-finally

0 голосов
/ 01 августа 2017

1.Мы можем использовать блок try без catch, но мы должны использовать catch / finally, любой из них.2.Мы не можем использовать только блок try.

0 голосов
/ 25 июня 2015

Вот пример использования, который я всегда (хм ..) использую:

int? x; //note the nullable type here!
try
{
    x = int.Parse(someString);
}
catch { } //don't care, let it just be null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...