【问题标题】:HttpWebRequest - GetResponse() - WebException ReceiveFailureHttpWebRequest - GetResponse() - WebException ReceiveFailure
【发布时间】:2013-07-23 02:16:41
【问题描述】:

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

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

的 WebException

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

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 文档,但这对我没有帮助。

【问题讨论】:

    标签: c# .net httpwebrequest webrequest system.net.webexception


    【解决方案1】:

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

    • WebExceptionStatus enum 不等同于您调用的 API 返回的 http 状态码。相反,它是在 http 调用期间可能发生的错误的枚举。
    • 当您从 API 收到错误(400 到 599)时,将返回的 WebExceptionStatus 错误代码是 WebExceptionStatus.ProtocolError,也就是整数 7。
    • 当需要获取响应体或者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.
    }
    

    【讨论】:

      【解决方案2】:

      这里在黑暗中拍摄......

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-29
        • 1970-01-01
        • 2020-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多