Подтвердить что ты не робот

Зачем использовать End in Try... Catch

Я вижу, что Finally in Try .. Catch всегда будет выполняться после любых частей выполнения блока catch try.

Можно ли просто пропустить раздел Finally и запустить его после, вне блока catch try?

Пример 1, Try... Catch... Наконец... End Try

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    Finally
        'Do cleanup
    End Try

Пример 2, Попробуйте... Catch... End Try... Сделайте, наконец, материал вне

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    End Try
    'Do cleanup
4b9b3361

Ответ 1

Да, это другое. Наконец, всегда будет выполняться (запрет программы). Если функция выходит из блока catch try или другая ошибка возникает либо в попытке, либо в catch, окончательно все равно будет выполняться. Вы не получите эту функциональность, не используя выражение finally.

Ответ 2

Код с четырьмя переключателями:

  • Возврат в TRY
  • Возврат в CATCH
  • Бросить в CATCH
  • Закончить CATCH

    private void checkFinally()
    {
        try
        {
            doFinally();
        }
        catch
        {
            Console.WriteLine(" Breaking news: a crash occured. ");
        }
    }
    
    private void doFinally()
    {
        Console.WriteLine(" ");
        Console.Write("Here goes: " 
            + (radioReturnInTry.Checked ? "2. Return in try: " 
                    : (radioReturnInCatch.Checked? "3. Retrun in catch: "
                        : (radioThrowInCatch.Checked? "4. Throw in catch: "
                            : "1. Continue in catch: "))) );
        try
        {
            if (radioReturnInTry.Checked)
            {
                Console.Write(" Returning in try. ");
                return;
            }
            Console.Write(" Throwing up in try.  ");
            throw new Exception("check your checkbox.");
        }
        catch (Exception ex)
        {
            Console.Write(" ...caughtcha! ");
            if (radioReturnInCatch.Checked)
            {
                Console.Write("Returning in catch. ");
                return;
            }
            if (radioThrowInCatch.Checked)
            {
                Console.Write(" Throwing up in catch. ");
                throw new Exception("after caught");
            }
        }
        finally { Console.Write(" Finally!!"); }
        Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, 
        // this would never happen (and was marked grey by ReSharper)
    
    }
    

Выход:

  • Вот так: 1. Продолжайте в catch: Бросайте в попытке.... caughtcha! В заключение!! Готово!!!
  • Вот так: 2. Вернитесь в попытке: вернусь в попытке. Наконец!!
  • Здесь: 3. Retrun in catch: Throwing in try.... caughtcha! Возвращение в улов. В заключение!!
  • Вот так: 4. Бросьте в ловушку: Бросай в попытку.... caughtcha! Бросание в улов. В заключение!! Последние новости: произошел сбой.

Подводя итог: Наконец, он заботится о двух вещах:

  • Код, который возвращает в try или в catch.
  • Или, если у вас есть исключение в try, и THROW исключение в catch,
  • или, если у вас есть исключение в попытке, И НЕ ОТКЛЮЧАЕТ это исключение,

Наконец, чтобы подвести итог "НАКОНЕЦ" : Наконец-то ничего особенного, если вы пробовали, и

  • НЕ ВОЗВРАЩАЕТСЯ,
  • и поймал все исключения во время пробного периода, а затем
  • DOT NOT RETURN в catch тоже, и
  • DIV NOT THROW или код, который подбрасывает.

И последнее, но не менее важное (наконец): Если в вашем коде есть исключение, которое ВЫ НЕ ПОЛУЧИЛИ, ваш код будет летать, БЕЗ ДОСТИЖЕНИЯ НАКОНЕЦ.

Надеюсь, это понятно. (Теперь это для меня...)

Моше

Ответ 3

Наконец, содержит код, который необходимо оценить при всех условиях [независимо от того, произошло ли исключение].

Невозможно выйти из блока try без выполнения его окончательного блока. Если блок finally существует, он всегда выполняется. (Это утверждение справедливо для всех целей и задач. Существует способ выхода из блока try без выполнения блока finally. Если код выполняет System.exit(0); изнутри блока try приложение завершается без окончательного с другой стороны, если вы отключите машину во время блока try, то, наконец, не будет выполняться.)

Основное использование - удаление объектов. Это будет полезно, если вы хотите закрыть пользователя определенные ресурсы, такие как файл, открытые ресурсы (db stmts).

Edit

И, наконец, не будет выполнен после исключения stackoverflow.

Ответ 4

Разница заключается в том, что код в блоке try генерирует исключение, которое не попадает в блок catch.

Обычно блок catch блокирует определенный тип исключения и пропускает все остальное. В этом случае блок finally все еще будет работать.

Блок finally также будет запущен, если код в блоке try return s.

Ответ 5

Это хорошая идея при работе с подключениями к базам данных или в любых случаях, когда необходимо удалить объекты. На всякий случай, если во время выполнения запросов что-то пойдет не так, вы все равно можете закрыть соединение. Это также помогает очистить код, который блок за пределами блока try/catch/finally не может получить доступ.

Ответ 6

Блок finally будет выполняться независимо от того, будет ли функция завершена из-за исключения. (есть некоторые исключения из этого правила, см. этот вопрос в стеке для получения дополнительной информации).

Например:

Try
    'Do something
Catch ex As Exception
    if 'Some Condition
       throw ex
    else
       'Handle exception
Finally
    'Do cleanup
End Try

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

Это хорошая практика, потому что она гарантирует, что ваш код очистки всегда будет выполняться. Конечно, используя Инициализация приобретения ресурсов, идиома - гораздо более чистый способ обеспечить очистку ресурсов, но я недостаточно разбираюсь в VB.net, чтобы узнать, можно ли это сделать.

Ответ 7

вы используете, наконец, код очистки, например, соединения db или открытые файлы, которые должны быть закрыты. Практически любой код очистки, который должен выполняться без исключения или не

Кроме того, для обработки исключений может потребоваться повторное исключение или другое исключение, и в этом случае код после блока не будет выполнен

Ответ 8

Выполнение очистки в блоке finally состоит в том, чтобы убедиться, что он запущен. Если блок catch не имеет отношения к исключению (т.е. Он просто регистрирует его) или даже вызывает другое исключение, код в блоке finally все равно будет выполняться.

Ответ 9

В дополнение к тому, что все остальные сказали, семантически, я думаю, что они разные.

Код в блоке finally четко указывает, что вы выполняете задачи типа завершения для содержимого, содержащегося в try-catch. Я думаю, это облегчает чтение.

Ответ 10

Насколько я помню, я никогда не использовал блок try/catch/finally в своем .NET-коде.

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

Итак, в среднем уровне вы будете чаще видеть try/finally (или инструкцию "using" ), чтобы очистить ресурсы. И в try/catch в обработчике верхнего уровня в уровне представления.

В редких случаях, когда мне нужно как поймать исключение, так и сделать некоторую очистку, я бы предпочел рефакторинг, чтобы следующее:

try
{
    ... do something
}
catch
{
   ... handle exception
}
finally
{
   ... cleanup
}

становится:

try
{
    DoSomethingAndCleanup();
}
catch
{
   ... handle exception
}

...
private void DoSomethingAndCleanup()
{
    try
    {
        ... do something
    }
    finally
    {
        ... cleanup
    }
}

ИМХО это намного чище.

Ответ 11

Наконец, нужно использовать все, что нужно сделать, чтобы поддерживать целостность системы. Обычно это означает, что ресурсы релиза

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

  • Завершить соединение
  • Закройте обработчик файлов
  • Свободная память
  • Закройте соединение с базой данных

Позвольте мне привести полный пример. Представьте, что вы отправляете сообщения через сеть. В псевдокоде:

// With finally                  |  //Without finally
try{                             |  try{  
  send_message()                 |    send_message() 
} catch(NetworkError){           |  } catch(NetworkError){ 
  deal_with_exception()          |    deal_with_exception()
} finally {                      |  }
  finalizes_connection()         |  finalizes_connection() 
}                                |

Единственное отличие обоих кодов заключается в том, что то, что удерживается в блоке try, вызывает исключение, которое не является NetworkError, например, MethodNotFound. В первом случае будет вызван метод finalizes_connection(), а во втором - нет.

Соединение, естественно, выполняется через несколько программ. Итак, что происходит в случае исключения MethodNotFound для другой программы? В первом случае ваша программа завершит соединение и другую программу, и она будет счастлива. Во втором случае другая программа может ждать вашего ответа навсегда. Что делать, если другая программа может получать только одно соединение за раз? Вы просто прослушали другую программу.

Это также относится к файлу, например, который вы открыли, и другие программы не смогут открывать для чтения (в Windows). И для памяти он никогда не выпускается, и теперь у вас есть утечка памяти.

Ответ 12

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

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

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

В принципе, очистка должна быть помещена в блок finally.

Ответ 13

Прочитав ответ на мой комментарий выше, я подумал о нескольких вещах.

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

Причина в том, что не все коды могут быть помещены в блок finally. Например. Отчеты yield не допускаются в блоках finally (и catch). В блоке try может быть несколько вариантов исполнения, где некоторые возвраты, а некоторые нет. Наконец, выполняется во всех этих случаях, тогда как в примере, когда, наконец, не было бы случая для кода очистки. Более того, вы не можете прыгать (goto) в блок finally, хотя очень редко вы можете перейти к коду после блока catch. Вы также не можете вернуться из блока finally.

Здесь довольно много, хотя самые необычные случаи, когда ответ зависит от фактического кода.

Ответ 14

То, что я часто использую, это (я инкапсулировал это в аспект, но это то, что я получил аспект):

public static DoLengthyProcessing(this Control control, Action<Control> action)
{
    Cursor oldCursor = control.Cursor
    try
    {
        control.Cursor = Cursors.WaitCursor;
        action(control);
    }
    catch (Exception ex)
    {
        ErrorHandler.Current.Handler(ex);
    }
    finally
    {
        control.Cursor = oldCursor;
    }
}

Или используйте AOP (как и я).