繁体   English   中英

HttpWebRequest - GetResponse() - WebException ReceiveFailure

[英]HttpWebRequest - GetResponse() - WebException ReceiveFailure

我有一个 WCF 服务,它每分钟运行频繁(1000+)个到外部 API 的出站连接。

我的代码经常抛出以下异常,但并不总是显示这是一个 WebException,其 WebException 状态属性为ReceiveFailure

发出出站请求的代码如下:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(paramBuilder.ToString());
request.ServicePoint.ConnectionLeaseTimeout = 0;
request.Method = "GET";
request.Timeout = 33000;    //33 Second Timeout Is By Design
Stream stream = default(Stream);
HttpWebResponse response = default(HttpWebResponse);
try
{

    response = (HttpWebResponse) request.GetResponse();
    stream = response.GetResponseStream();
    reader = new StreamReader(stream,Encoding.UTF8);
    string str = reader.ReadToEnd();
    return str;

}
catch (WebException exception)
{

    //Handle WebException
}
catch (Exception exception)
{
    //Handle Exception
}
finally
{
    if (reader != null)
        reader.Dispose();

    if (response != null)
        response.Close();

    if (stream != null)
        stream.Dispose();
}

异常堆栈跟踪显示异常是由 GetResponse() 引起的。

我偶尔会收到一个 WebException -ReceiveFailure,这可能是什么原因造成的。

我已经参考了有关此状态的 MSDN 文档,但这对我没有帮助。

在这里暗中拍摄...

在等待响应时有一个特殊情况:如果系统时钟是由 Windows 时间服务自动设置的,或者是手动设置的,您可能会遇到一些不可预知的结果。

如果您通过 HTTPS 发送您的请求,那么您可能会遇到错误地作为 ReceiveFailure 抛出的常规超时。

查看这篇文章了解更多信息: http : //support.microsoft.com/kb/2007873

我有一个相关的问题,我在寻找解决方案时意识到了一些事情。

  • WebExceptionStatus enum不等同于您调用的 API 返回的 http 状态代码。 相反,它是在 http 调用期间可能发生的可能错误的枚举。
  • 当您从 API 收到错误(400 到 599)时将返回的WebExceptionStatus错误代码是WebExceptionStatus.ProtocolError又名数字 7 作为 int。
  • 当需要获取api返回的响应体或者真实的http状态码时,首先需要检查WebException.Status是否为WebExceptionStatus.ProtocolError 然后你可以从WebExceptionStatus.Response获取真正的响应并读取其内容。
  • 有时超时由调用者(也就是您的代码)处理,因此在这种情况下您没有响应。 所以你可以看看WebException.Status是否是WebExceptionStatus.Timeout

这是一个例子:

try
{
    ...
}
catch (WebException webException)
{
    if (webException.Status == WebExceptionStatus.ProtocolError)
    {
        var httpResponse = (HttpWebResponse)webException.Response;
        var responseText = "";
        using (var content = new StreamReader(httpResponse.GetResponseStream()))
        {
            responseText = content.ReadToEnd(); // Get response body as text
        }
        int statusCode = (int)httpResponse.StatusCode; // Get the status code
    }
    else if (webException.Status == WebExceptionStatus.ProtocolError)
    {
       // Timeout handled by your code. You do not have a response here.
    }

    // Handle other webException.Status errors. You do not have a response here.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM