Error loading HttpClient file. Unable to read data from transport connection.

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:

  • The error always occurs in the middle of the download (never when the request starts).

  • The file continues to load until failure (at first there are no long pauses or delays).

- 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()
{
    // In case we're taxing the web server, limit the number
    // connections we're allowed to make to one.
    ServicePointManager.DefaultConnectionLimit = 1;

    // Set up the progress handler so that we can keep track of the download progress.
    _progressHandler = new ProgressMessageHandler();
    _progressHandler.HttpReceiveProgress += ProgressHandler_HttpReceiveProgress;

    // Create our HttpClient.
    _client = HttpClientFactory.Create(_progressHandler);
    _client.BaseAddress = new Uri("http://localhost");
    _client.Timeout = TimeSpan.FromMinutes(30);
    _client.DefaultRequestHeaders.TransferEncodingChunked = true;
}

:

private void StartDownload()
{
    // Create the request.
    using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Download"))
    {
        // Revert the protocol version and turn off keep alive in accordance with:
        // http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/
        // http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

        request.Version = new Version("1.0");
        request.Headers.Add("Keep-Alive", "false");

        // Set the cancellation token timeout to 30 minutes.
        int timeoutInMilliseconds = 30 * 60 * 1000;

        using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(timeoutInMilliseconds))
        {
            // Making sure that the message isn't "complete" until everything is read in so we can cancel it at anytime.
            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)
                {
                    // TODO: Save to disk.
                }
            }
        }
    }
}
+4

All Articles