HttpWebRequest-GetResponse()-WebException接收失败
本文关键字:失败 -WebException HttpWebRequest-GetResponse | 更新日期: 2023-09-27 18:24:27
我有一个WCF服务,它每分钟运行到外部API的频繁(1000+)出站连接。
我的代码经常抛出以下异常,但并不总是显示这是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.
}