c# - HttpWebRequest 未处理 "invalidcastexception"将 HttpWebResponse 转换为 System.Exception

标签 c# exception casting httpwebrequest

我们有一个应用程序,它使用 HttpWebRequest 类调用远程 Web 地址,我们通过 WebRequest.Create 方法获取该类。

这是我们的实际代码:

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

Unable to cast object of type 'System.Net.HttpWebResponse' to type 'System.Exception'.

使用此堆栈跟踪:

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult)

at System.Net.LazyAsyncResult.Complete(IntPtr userToken)

at System.Net.ContextAwareResult.CaptureOrComplete(ExecutionContext& cachedContext, Boolean returnContext)

at System.Net.ContextAwareResult.FinishPostingAsyncOp()

at System.Net.HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)

有关此方法的文档报告了几个可以引发的异常,但 InvalidCastException 不是其中之一,这意味着它在 Microsoft 方法中未处理。 我开始挖掘 .Net 源代码,我想我找到了罪魁祸首。在 HttpWebResponse.EndGetResponseStream 方法中,有这样一行:

throw (Exception) lazyAsyncResult.Result;

这是此方法中唯一存在的 Exception 转换,因此一定是它。现在,该方法的实现方式是,仅当连接流为 null 时才会到达此行,因此 lazyasyncresult.Result 属性应包含异常。然而,就我而言,已到达分支,但 lazyasyncresult.Result 包含 HttpWebResponse,因此装箱失败,我收到该错误。现在我有两个考虑:

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

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

下面是该方法的 MS 源,供引用。我在受罪的线路上添加了一些评论。

感谢大家的宝贵时间。

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;
        }
      }
    }

最佳答案

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

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

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

关于c# - HttpWebRequest 未处理 "invalidcastexception"将 HttpWebResponse 转换为 System.Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18097301/

相关文章:

c# - SharpSsh 命令执行

java - 异常:"attempt to access org.rosuda.REngine.REXPGenericVector as String"

Java 将 Image 转换为 BufferedImage

c++ - 由于从 C 到 C++ 的类型转换,无法编译并出现错误 C2440

c# - 无法将类型 'System.Data.Entity.Core.Objects.ObjectResult<>' 隐式转换为 'System.Collections.Generic.List<>'

c# - 编辑 Xml 节点

c# - Visual Studio - 抑制某些 "Exception thrown"消息

c - C 中的异常处理 - 使 try catch 跨函数工作

java - 在 java 中将 byte[] salt 转换为 String

c# - 如何在 c# 的 ms word 文档中为多语言文本设置字体?