Я ищу советы о том, как обрабатывать любые исключения, в следующем примере кода:Как лучше обрабатывать исключения при использовании HttpWebResponse
private string SendRequest()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myURL);
// Code initialising HttpWebRequest
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream rcvdStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(rcvdStream, Encoding.UTF8);
string responseString = readStream.ReadToEnd();
response.Close();
readStream.Close();
return responseString;
}
Моя главная задача заключается в обеспечении StreamReader и HttpRequest объекта закрыты когда метод заканчивается. Должен ли я:
- Оберните много вверх в Try/улове/наконец регистрация каких-либо исключений в блоке улова и закрытие потока в конце концов блока?
- Используйте инструкцию using для создания объекта объекта HttpWebRequest и вложенный оператор using при создании StreamReader?
- Не беспокойтесь об этом и предположите, что GC очистит все, когда объекты выйдут из сферы действия по мере выхода метода?
EDIT: Дальнейшее исследование показало, что вариант 2 может быть сделано без вложенности с помощью заявления:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream rcvdStream = response.GetResponseStream())
{
StreamReader readStream = new StreamReader(rcvdStream, Encoding.UTF8);
payResponse = readStream.ReadToEnd();
}
Это приводит следующий IL код, который демонстрирует, что она эффективно создать вложенную попробовать/окончательный блок:
IL_00b0: callvirt instance class [System]System.Net.WebResponse [System]System.Net.WebRequest::GetResponse()
IL_00b5: castclass [System]System.Net.HttpWebResponse
IL_00ba: stloc.s response
.try
{
IL_00bc: ldloc.s response
IL_00be: callvirt instance class [mscorlib]System.IO.Stream [System]System.Net.WebResponse::GetResponseStream()
IL_00c3: stloc.s rcvdStream
.try
{
IL_00c5: nop
IL_00c6: ldloc.s rcvdStream
IL_00c8: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8()
IL_00cd: newobj instance void [mscorlib]System.IO.StreamReader::.ctor(class [mscorlib]System.IO.Stream,
class [mscorlib]System.Text.Encoding)
IL_00d2: stloc.s readStream
IL_00d4: ldloc.s readStream
IL_00d6: callvirt instance string [mscorlib]System.IO.TextReader::ReadToEnd()
IL_00db: stloc.3
IL_00dc: nop
IL_00dd: leave.s IL_00f3
} // end .try
finally
{
IL_00df: ldloc.s rcvdStream
IL_00e1: ldnull
IL_00e2: ceq
IL_00e4: stloc.s CS$4$0001
IL_00e6: ldloc.s CS$4$0001
IL_00e8: brtrue.s IL_00f2
IL_00ea: ldloc.s rcvdStream
IL_00ec: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_00f1: nop
IL_00f2: endfinally
} // end handler
IL_00f3: nop
IL_00f4: leave.s IL_010a
} // end .try
finally
{
IL_00f6: ldloc.s response
IL_00f8: ldnull
IL_00f9: ceq
IL_00fb: stloc.s CS$4$0001
IL_00fd: ldloc.s CS$4$0001
IL_00ff: brtrue.s IL_0109
IL_0101: ldloc.s response
IL_0103: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0108: nop
IL_0109: endfinally
} // end handler
Я рад, что работает для вас, но FYI, эти два с использованием утверждений _are_ вложены. На внешнем уровне не должно быть никаких фигурных скобок. –
Справедливая точка, и я думаю, что это продемонстрировано в IL. –