Это в порядке для встраивания "попытки/выгоды" в операторе "использования" для веб-запроса? Мой код является правильным? Это - мои требования:
Хочу использовать оператор "использования", чтобы удостовериться, что средства высвобождены в любом случае на HttpWebResponse
Мой исходный код:
var result = new HttpHeaderInfo();
HttpWebRequest request = null;
HttpWebResponse response = null;
using (response)
{
try
{
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "HEAD";
request.KeepAlive = false;
request.Timeout = Properties.Settings.Default.WebTimeoutDefault;
response = (HttpWebResponse)request.GetResponse();
result.LastModified = response.LastModified;
result.ContentType = response.ContentType;
result.StatusCode = response.StatusCode;
result.ContentLength = response.ContentLength;
}
catch (Exception ex)
{
if (ex is InvalidOperationException ||
ex is ProtocolViolationException ||
ex is WebException)
{
result.HttpError = ex;
result.LastModified = System.DateTime.MinValue;
result.ContentType = null;
}
else { throw; }
}
}
спасибо
Это нормально, но немного избыточно; в общем смысле, вы можете легко удалить с помощью блока
, добавить блок finally
после catch
и явно вызвать Dispose
в там, что уменьшит вложенность в ваш код.
В более конкретном смысле меня немного беспокоит то, что вы фактически не назначаете ответ
, пока не получите внутри с использованием блока
, и явные объявления переменных не нужны и сбивают с толку в этом контексте. Я бы переписал его так:
HttpHeaderInfo result;
try
{
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "HEAD";
request.KeepAlive = false;
request.Timeout = Properties.Settings.Default.WebTimeoutDefault;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
result = new HttpHeaderInfo();
result.LastModified = response.LastModified;
result.ContentType = response.ContentType;
result.StatusCode = response.StatusCode;
result.ContentLength = response.ContentLength;
}
}
catch (WebException ex)
{
// etc.
}
Это намного яснее, чем исходная форма. Также обратите внимание, что я перехватываю WebException
, а не общий System.Exception
. Вы должны перехватывать определенные типы исключений вместо того, чтобы перехватывать общие исключения и затем проверять их тип.
Другие указали Это потенциал потенциал проблема , но я хочу поднять его как , очень определенный Проблема: Ваше используемое утверждение делает вас не совсем хорошим в данный момент.
Когда вы пишете используемую оператор, подобное это:
SomeType x = value1;
using (x)
{
x = value2;
}
Это значение1
, которое будет расположено в конце блока, не значение2
. В вашем коде ответ
- это нулевой до блока; WEBRESPOSS
Вы в конечном итоге с волей нет .
Вы должны видеть предупреждение об этом, вдоль этих строк:
Предупреждение CS0728: Возможно неправильное назначение для местных «Ответ», который это аргумент с использованием или заблокированным оператором. Утилизация вызова или Разблокировка произойдет по первоначальной стоимости местного.
Это предупреждение важно - прислушиваясь.
Оставив это в сторону, совершенно разумно поставить блок Thrue / Catch в используемом операторе ... но в этом случае он, вероятно, должен быть снаружи Оператор использования, позволяющий инициализировать Ответ
переменная в подходящее время, чтобы ответ всегда был утилизирован. Я также рассмотрел бы использование нескольких блоков CALL, вызывающих общий метод, а не использование «многократно».
Это совершенно нормально. Вы обрабатываете исключение и не хотите, чтобы он был дальше, это просто отлично, и вложенная попытка / уловка / наконец-то не проблема. (Внутренне «используя», как это просто попытка / наконец.)
Обновление: прочитайте немного ближе, и я думаю, что вы на самом деле хотите использовать в блоке «Попробуйте» - строку, в которой вы фактически помещаете объект в Переменная «Ответ» - это то, где вы хотите начать блок «Использовать». Это на самом деле компилирует как есть?