我们在WebApi端点中间歇性地收到The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available
异常。
是否有人知道导致此错误的原因,或者如何以一致的方式重现该错误?目前,它发生在100,000个请求中的150个中。
XmlDeserialize()
在此部分代码中引发了异常:
[HttpPost]
public async Task<IHttpActionResult> Process()
{
using (var requestStream = await Request.Content.ReadAsStreamAsync())
{
XmlSerializer serializer = new XmlSerializer(typeof(MyEntity));
// !! The below line throws the exception
MyEntity entity = serializer.Deserialize(requestStream) as MyEntity;
}
...
}
这是完整的异常消息:
"ExceptionType": "HttpException",
"Message": "The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available.",
"StackTrace": [
"HttpBufferlessInputStream.Read;0",
"SeekableBufferedRequestStream.Read;0",
"XmlTextReaderImpl.ReadData;0",
...
编辑:我在.NET的源代码中找到了它。 System.Web.txt:
HttpBufferlessInputStream_ClientDisconnected=The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available.
https://referencesource.microsoft.com/#system.web/HttpBufferlessInputStream.cs,332ecbede7a1f12a:
// We are done if the count == 0 or there is no more content
while (count > 0 && _remainingBytes != 0) {
// Do the actual read
bytesRead = wr.ReadEntityBody(buffer, offset, count);
if (bytesRead <= 0) {
if (!_context.Response.IsClientConnected) {
if (_persistEntityBody) {
SetRawContentOnce();
}
throw new HttpException(SR.GetString(SR.HttpBufferlessInputStream_ClientDisconnected));
因此,在wr.ReadEntityBody(buffer, offset, count)
返回0或负数并且_context.Response.IsClientConnected
为false之后,HttpBufferlessInputStream.Read()会引发异常。
这意味着XmlDeserialize()仍在运行时,客户端已断开连接。但是根据我对netcat的有限实验,.NET一直等到整个XML请求都已上传,甚至没有调用controller方法。因此,我们在反序列化时就不会上传请求。
答案 0 :(得分:3)
就像已经解释过的here一样,您应该避免捕获同步上下文并使用.ConfigureAwait(false);
[HttpPost]
public async Task<IHttpActionResult> Process()
{
using (var requestStream = await Request.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyEntity));
MyEntity entity = serializer.Deserialize(requestStream) as MyEntity;
}
...
}
Thowk,SynchronizationContext has been removed from ASP.NET Core注意到了。
答案 1 :(得分:0)
我认为其为空数据或执行超时问题。尝试捕获事件的时间和数据以及返回的api调用的数据。尝试使用控制台应用程序进行一些压力测试。 检查您的IIS或Web服务器日志。 关于您的代码的异步方法 添加多余的行
string str = response.Content.ReadAsStringAsync().Result;
编写str进行记录并检查其中包含什么数据。 尝试将其转换为同步方法。
更改您的超时时间。
<system.web>
<httpRuntime executionTimeout="180" />
</system.web>