使用HttpWebResponse时如何最好地处理异常

时间:2009-04-06 13:51:30

标签: c# exception-handling

我正在寻找有关如何处理以下代码示例中抛出的任何异常的建议:

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 / catch / finally中记录批次,在catch块中记录任何异常并关闭finally块中的流吗?
  2. 在创建StreamReader时,在HttpWebRequest对象实例化和嵌套的using语句上使用using语句?
  3. 不用担心它并假设当方法退出时,当对象超出范围时GC会清除所有内容?
  4. 编辑:进一步的调查显示,可以在不嵌套using语句的情况下完成选项2:

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using (Stream rcvdStream = response.GetResponseStream())
        {
            StreamReader readStream = new StreamReader(rcvdStream, Encoding.UTF8);
            payResponse = readStream.ReadToEnd();
        }
    

    这将生成以下IL代码,该代码演示了它是否有效地创建了嵌套的try / finally块:

      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
    

1 个答案:

答案 0 :(得分:2)

选项一和二是你最好的选择。选项3不是一个好主意。

我个人非常喜欢Using statement route。但是,try / catch / finally路由基本相同,并为您提供所需的日志记录机制。