2009-04-06 2 views
3

Я ищу советы о том, как обрабатывать любые исключения, в следующем примере кода:Как лучше обрабатывать исключения при использовании 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 объекта закрыты когда метод заканчивается. Должен ли я:

  1. Оберните много вверх в Try/улове/наконец регистрация каких-либо исключений в блоке улова и закрытие потока в конце концов блока?
  2. Используйте инструкцию using для создания объекта объекта HttpWebRequest и вложенный оператор using при создании StreamReader?
  3. Не беспокойтесь об этом и предположите, что 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 
+0

Я рад, что работает для вас, но FYI, эти два с использованием утверждений _are_ вложены. На внешнем уровне не должно быть никаких фигурных скобок. –

+0

Справедливая точка, и я думаю, что это продемонстрировано в IL. –

ответ

2

Варианты 1 и 2 - ваши лучшие ставки. Вариант 3 НЕ является хорошей идеей.

Я лично очень люблю использование инструкции Statement. Тем не менее, маршрут try/catch/finally по сути тот же, и предоставляет вам необходимый механизм ведения журнала.

Смежные вопросы