【问题标题】:How best to handle exceptions when using HttpWebResponse使用 HttpWebResponse 时如何最好地处理异常
【发布时间】:2009-04-06 13:51:30
【问题描述】:

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

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. 在 HttpWebRequest 对象实例化上使用 using 语句,在创建 StreamReader 时使用嵌套 using 语句?
  3. 不用担心,并假设当方法退出时对象超出范围时,GC 会清除所有内容?

编辑:进一步调查表明,选项 2 可以在不嵌套 using 语句的情况下完成:

    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

【问题讨论】:

  • 我很高兴这对你有用,但仅供参考,这两个 using 语句 嵌套的。只是碰巧外面没有大括号。
  • 公平点,我认为这在 IL 中得到了证明。

标签: c# exception-handling


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2011-01-29
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多