Должен ли try / catch быть внутри или снаружи блока использования?
на using
block-сокращение от try/catch/finally
Я верю. В моем коде я ставил try/catch
блок внутри the using
блок, так что я могу поймать и регистрировать исключения с помощью моего собственного регистратора.
мне недавно было интересно, если try
должно быть снаружи, таким образом, инкапсулируя using
блок, или нет.
на мой взгляд, я уже боялся, что если исключение, то using
блок не будет Dispose()
of мой ресурс, потому что он выпрыгнул из блока и в обработчик catch. Но я могу ошибаться.
может кто-нибудь уточнить, какой правильный способ использовать оба using
и try/catch
вместе?
public HttpResponseMessage GetData(string x, int y)
{
using (var client = new HttpClient())
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
}
5 ответов
using
блок используется для обеспечения удаления (изменен с неоднозначного термина "немедленное удаление" на удаление, как предложено Джеймс) объектов, объявленных в using
оператор, как только код выходит из using
блок. Это не совсем сокращение для try/catch/finally
. (Обратите внимание, что компилятор интерпретирует его как try-finally однако)
в вашем примере
using (var client = new HttpClient())
{
} //client will be disposed at any time after this line
зависит от случая, вы может рассмотреть поставить try-catch
блок внутри или за пределами using
блок.
например, если вам не нужно использовать элемент using
объявление несколько раз (edit :что я имею в виду, если вам нужен элемент и на try
и catch
block-спасибо за ввод Мистер Коди Серый) - то есть, вам это нужно только в try
, Я бы предложил использовать using
блок внутри try
заблокировать.
переведена на ваш случай, это зависит от того,var client
предназначен для использования как для try
и catch
блоки. Если это так, то using
должно быть вне try-catch
блок. Иначе он должен быть внутри try
заблокировать.
в общем, как правило, если элемент используется как в try
и catch
блок, а затем объявить using
только один раз за пределами try-catch
это действительно зависит от того, какой ресурс вы беспокоитесь о том, чтобы быть утилизированным - если вы имеете в виду client
вы должны быть хорошо. Я объясню, почему...
на мой взгляд, я ранее волновался, что если будет выброшено исключение, то блок using не будет Dispose() моего ресурса, потому что он выскочил из блока и в обработчик catch. Но я могу ошибаться.
Это не так, компилятор, вероятно, переписать код (возможно, более эффективно), например:
try
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
finally
{
if (client != null)
client.Dispose();
}
под нормальный обстоятельства a finally
блок всегда будет выполняться, что означает, даже если вы ловите/повторной генерации исключения внутри using
ваш Dispose
вызов будет запущен.
таким образом, с технической точки зрения, внутри и снаружи не имеет значения.
на нем нет" правильного пути", только рекомендации. Однако я сам пытаюсь локализовать каждое исключение или любой код, насколько это возможно, то есть вы должны исключение, где оно может быть брошено, но где-то снаружи, по крайней мере, пока вам не нужно позволять вашему исключению пузыриться через разные слои.
в любом случае будет работать. Использование блоков гарантированно всегда вызывает Dispose()
метод при выходе-это верно даже для стека un-ravelling для исключений, пойманных дальше по стеку.
посмотреть оператор using (ссылка на C#)
оператор using гарантирует, что метод Dispose вызывается даже если исключение возникает при вызове методов объекта. Вы можете достичь того же результата путем помещения объекта внутри блока try и затем вызов Dispose в блоке finally; фактически, именно так оператор using переводится компилятором. Пример кода ранее расширяется до следующего кода во время компиляции (обратите внимание на дополнительные фигурные скобки для создания ограниченной области для объекта):
лично я бы поставил try / catch / finally внутри using
заблокировать.
Причина этого просто в том, что блок не будет бросать исключение, по крайней мере, не из моего опыта. Поэтому для простоты я буду иметь дело с исключениями, когда они происходят.