首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HttpWebRequest未处理的“无效异常”将HttpWebResponse转换为System.Exception

HttpWebRequest未处理的“无效异常”将HttpWebResponse转换为System.Exception
EN

Stack Overflow用户
提问于 2013-08-07 07:34:05
回答 1查看 1.1K关注 0票数 2

我们有一个应用程序,它使用HttpWebRequest类调用远程web地址,这是通过WebRequest.Create方法得到的。

这是我们的实际代码:

代码语言:javascript
运行
复制
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "HEAD";
request.Timeout = this.connectionTimeout;

if (this.usePipelinedConnection)
{
     request.KeepAlive = true;
     request.Pipelined = true;
}

request.BeginGetResponse(cb => logService.EndGetRequestStream(cb), null);

现在,以一种不确定的方式(无法找到一个模式来再现它),我们得到了以下错误:

System.InvalidCastException 无法将“System.Net.HttpWebResponse”类型的对象强制转换为“System.Exception”类型。

使用此堆栈跟踪:

在System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context) 在System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult) 在System.Net.LazyAsyncResult.Complete(IntPtr userToken) 在System.Net.ContextAwareResult.CaptureOrComplete(ExecutionContext& cachedContext,布尔returnContext) 在System.Net.ContextAwareResult.FinishPostingAsyncOp() 在System.Net.HttpWebRequest.BeginGetResponse(AsyncCallback回调时,对象状态)

有关此方法的文档报告了一些可以抛出的异常,但InvalidCastException不是其中之一,这意味着它在microsoft中是无法处理的。我开始挖掘.Net的来源,我想我找到了罪魁祸首。在HttpWebResponse.EndGetResponseStream方法中,有以下一行:

代码语言:javascript
运行
复制
throw (Exception) lazyAsyncResult.Result;

这是此方法中唯一存在的异常类型,所以必须是它。现在实现方法的方式是,只有当连接流为null时,它才会到达该行,因此lazyasyncresult.Result属性应该包含一个异常。然而,在我的例子中,到达了分支,但是lazyasyncresult.Result包含一个HttpWebResponse,因此装箱失败,我得到了这个错误。现在我有两个考虑:

  • 如果lazyasyncresult.Result的内容是正确的,它无论如何都会抛出(因为行以抛起),但这将是一个有意义的错误;
  • 与前面的一点相关,我认为如果我有一个HttpWebResponse,那么无论如何都不应该到达抛出的代码分支

现在,我的问题很简单:我如何防止这种情况发生?我在代码中做错了什么,还是在MS方法中是一个普通的bug?

以下是该方法的MS源,供参考。我对这句指名道姓的话增加了一些评论。

谢谢大家抽出时间。

代码语言:javascript
运行
复制
public Stream EndGetRequestStream(IAsyncResult asyncResult, out TransportContext context)
    {
      if (Logging.On)
        Logging.Enter(Logging.Web, (object) this, "EndGetRequestStream", "");
      context = (TransportContext) null;
      if (asyncResult == null)
        throw new ArgumentNullException("asyncResult");
      LazyAsyncResult lazyAsyncResult = asyncResult as LazyAsyncResult;
      if (lazyAsyncResult == null || lazyAsyncResult.AsyncObject != this)
        throw new ArgumentException(SR.GetString("net_io_invalidasyncresult"), "asyncResult");
      if (lazyAsyncResult.EndCalled)
      {
        throw new InvalidOperationException(SR.GetString("net_io_invalidendcall", new object[1]
        {
          (object) "EndGetRequestStream"
        }));
      }
      else
      {
        ConnectStream connectStream = lazyAsyncResult.InternalWaitForCompletion() as ConnectStream;
        lazyAsyncResult.EndCalled = true;
        if (connectStream == null)
        {
          if (Logging.On)
            Logging.Exception(Logging.Web, (object) this, "EndGetRequestStream", lazyAsyncResult.Result as Exception);

// Here result contains HttpWebResponse so the cast to Exception fails. 
// It would throw anyway (since there' a throw) but I think, since result contains a response
// that the code shouldn't be hitting this if branch.
          throw (Exception) lazyAsyncResult.Result;
        }
        else
        {
          context = (TransportContext) new ConnectStreamContext(connectStream);
          if (Logging.On)
            Logging.Exit(Logging.Web, (object) this, "EndGetRequestStream", (object) connectStream);
          return (Stream) connectStream;
        }
      }
    }
EN

回答 1

Stack Overflow用户

发布于 2015-02-27 01:08:28

我从来没有使用过这个异步任务库,如果这是一个天真的问题,请原谅我。但是..。你打错了EndGetXXX函数吗?

request.BeginGetResponse(cb => logService.EndGetRequestStream(cb), null);

我不知道logService变量是什么,但是它不应该调用EndGetResponse()吗?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18097301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档