Используйте блок "try-finally" без блока "catch" - программирование
Подтвердить что ты не робот

Используйте блок "try-finally" без блока "catch"

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

4b9b3361

Ответ 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.

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

Ответ 5

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

См. также try-finally

Ответ 6

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

Ответ 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.