I wrote an application that can partially download files from a specific web service. The code uses HttpClient to make calls. The problem is that sometimes I get a failed request with the following exception message:
Unable to read data from transport connection: connection was closed.
I came across these blog posts in which the author had to cancel the protocol version to 1.0, disable support, and limit the number of service point connections:
I followed these instructions, as I knew better how I still got the error. I also had to support one instance of HttpClient (following the Singleton principle).
Interestingly, when I started Fiddler, I still didn’t get an error, which makes me think that there is something that can be done on the client side, since Fiddler seems to be doing something to keep in touch (although the problem is so sporadic that it may be a red herring).
A few more notes:
- UPDATE -
The error occurs on the following line:
responseTask.Wait(cancellationTokenSource.Token);
The following is the complete exception:
System.AggregateException occurred HResult=-2146233088 Message=One
or more errors occurred. Source=mscorlib StackTrace:
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at Form1.StartDownload() in c:\Projects\Visual Studio 2012\Demo\Demo\Form1.cs:line 88 InnerException:
System.Net.Http.HttpRequestException
HResult=-2146233088
Message=Error while copying content to a stream.
InnerException: System.IO.IOException
HResult=-2146232800
Message=Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Source=System
StackTrace:
at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.EndRead(IAsyncResult
asyncResult)
at System.Net.Http.Handlers.ProgressStream.EndRead(IAsyncResult
asyncResult)
at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)
InnerException: System.Net.Sockets.SocketException
HResult=-2147467259
Message=An existing connection was forcibly closed by the remote host
Source=System
ErrorCode=10054
NativeErrorCode=10054
StackTrace:
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
InnerException:
- UPDATE # 2 -
, " " " ". , ( TODO, ).
- # 3 -
, - ( IIS) ( IIS win32 1236 - ERROR_CONNECTION_ABORTED). , MinFileBytesPerSec (, ), . , . . .
:
private void SetupClient()
{
ServicePointManager.DefaultConnectionLimit = 1;
_progressHandler = new ProgressMessageHandler();
_progressHandler.HttpReceiveProgress += ProgressHandler_HttpReceiveProgress;
_client = HttpClientFactory.Create(_progressHandler);
_client.BaseAddress = new Uri("http://localhost");
_client.Timeout = TimeSpan.FromMinutes(30);
_client.DefaultRequestHeaders.TransferEncodingChunked = true;
}
:
private void StartDownload()
{
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Download"))
{
request.Version = new Version("1.0");
request.Headers.Add("Keep-Alive", "false");
int timeoutInMilliseconds = 30 * 60 * 1000;
using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(timeoutInMilliseconds))
{
Task<HttpResponseMessage> responseTask = _client.SendAsync(request, HttpCompletionOption.ResponseContentRead);
responseTask.Wait(cancellationTokenSource.Token);
using (HttpResponseMessage response = responseTask.Result)
{
if (!response.IsSuccessStatusCode)
{
throw new Exception("Request failed!");
}
Task<Stream> streamTask = response.Content.ReadAsStreamAsync();
using (Stream contentStream = streamTask.Result)
{
}
}
}
}
}