I am using the HttpClient class in .NET Framework 4.5.2.
I calling PostAsync against a third party web service. 80% of the time this post works, 20% of the time our response is cut short. In this situation we get the following exception:
System.Net.Http.HttpRequestException: Error while copying content to
a stream. ---> System.IO.IOException: Unable to read data from the
transport connection: An existing connection was forcibly closed by
the remote host. ---> System.Net.Sockets.SocketException: An existing
connection was forcibly closed by the remote host at
System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32
offset, Int32 size, AsyncCallback callback, Object state) --- End
of inner exception stack trace --- at
System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32
offset, Int32 size, AsyncCallback callback, Object state) at
System.Net.FixedSizeReader.StartReading() at
System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32
offset, Int32 count, AsyncProtocolRequest asyncRequest) at
System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32
offset, Int32 count, AsyncProtocolRequest asyncRequest) at
System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32
offset, Int32 count, AsyncProtocolRequest asyncRequest) at
System.Net.TlsStream.BeginRead(Byte[] buffer, Int32 offset, Int32
size, AsyncCallback asyncCallback, Object asyncState) at
System.Net.ConnectStream.BeginReadWithoutValidation(Byte[] buffer,
Int32 offset, Int32 size, AsyncCallback callback, Object state) at
System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32
size, AsyncCallback callback, Object state) at
System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[]
buffer, Int32 offset, Int32 count, AsyncCallback callback, Object
state) at System.Net.Http.StreamToStreamCopy.StartRead()
A subsequent identical request succeeds.
We cannot retry this request as the business action has already been taken. So it leaves us in an awkward situation.
This is my code:
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
}
The third-party service are successfully saving the record to their database and do not see any obvious exceptions at their end. They did note that the failing requests generally took longer (around 18-30 seconds) to write to the database than the successful requests.
What can I do to handle this better?
See Question&Answers more detail:
os