System.Net.Http.HttpRequestException将内容复制到流时出错

我在.Net 4.5.2框架中使用HttpClient类。 我正在对第三方Web服务进行PostAsync。 这篇文章有80%的时间有效,20%的时间我们的回复被缩短了。 在这种情况下,我们得到以下exception:

System.Net.Http.HttpRequestException: 将内容复制到流时出错。 —> System.IO.IOException:无法从传输连接读取数据:远程主机强制关闭现有连接。 —> System.Net.Sockets.SocketException:远程主机在System.Net.Sockets.NetworkStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32大小,AsyncCallback回调,对象状态)强制关闭现有连接—内部exception堆栈跟踪的结束—在System.Net.FixedSizeReader.StartReading()的System.Net.Sockets.NetworkStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32大小,AsyncCallback回调,对象状态)在System.Net.Security._SslStream.StartFrameHeader(Byte []缓冲区,Int32偏移量,Int32计数,AsyncProtocolRequest asyncRequest)处于System.Net.Security._SslStream.StartReading(Byte []缓冲区,Int32偏移量,Int32计数,AsyncProtocolRequest asyncRequest)在System.Net.Security.PlsStream.BrocessRead(Byte []缓冲区,Int32偏移量,Int32计数,AsyncProtocolRequest asyncRequest)处于System.Net.TlsStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32大小,AsyncCallback asyncCallback,Object asyncState) )在System.Net.ConnectStream.BeginReadWithoutValidation(Byte []) System.Net.Http.HttpClientHandler.WebExceptionWrapperStream上的System.Net.ConnectStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32大小,AsyncCallback回调,对象状态)处的缓冲区,Int32偏移量,Int32大小,AsyncCallback回调,对象状态) System.Net.Http.StreamToStreamCopy.StartRead()的.BeginRead(Byte []缓冲区,Int32偏移量,Int32计数,AsyncCallback回调,对象状态)

随后的相同请求成功。 这不是我们可以重新设置的请求,因为已经放置了业务。 所以它让我们陷入了尴尬境地。

这是我的代码:

using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Authorization = authorizationHeader; HttpContent httpContent = new StringContent(someXml); //Exception occurs on next line... var response = await httpClient.PostAsync("https://thirdpartyendpoint", httpContent); var responseXml = await response.Content.ReadAsStringAsync(); //convert to Dto } 

第三方服务成功地将记录保存到他们的数据库中,并且在他们的结尾没有看到任何明显的例外。 他们确实注意到,写入数据库的失败请求通常需要比成功请求更长的时间(大约18-30秒)。

谢谢您的帮助

我们用2个代码更改解决了这个问题:

  1. 处理httpResponseMessage并使用简单的DTO

      using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) { return await CreateDto(httpResponseMessage); } 
  2. 将HTTP版本降级到v1.0

     var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(url)) { Version = HttpVersion.Version10, Content = httpContent }; await client.SendAsync(httpRequestMessage); 

这有添加这个Http头的效果

  Connection: close 

而不是这个

  Connection: keep-alive