Bug 58641 - Cannot access a disposed object error in System.Net.Sockets.NetworkStream
Summary: Cannot access a disposed object error in System.Net.Sockets.NetworkStream
Status: CONFIRMED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Net.Http (show other bugs)
Version: 5.4.0 (2017-06)
Hardware: Other Linux
: --- normal
Target Milestone: Future Release
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-08-08 12:06 UTC by Andy
Modified: 2017-09-14 10:14 UTC (History)
3 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Andy 2017-08-08 12:06:14 UTC
Running Mono 5.4.0.36

When using a HttpClient to download and you set the HttpCompletionOption to ResponseHeadersRead, if you then read the HttpResponseMessage content and pass it to a file stream to copy to you will get a "Cannot access a disposed object."

var httpClient = new HttpClient();
var response = httpClient.GetAsync("SomeURL", HttpCompletionOption.ResponseHeadersRead).Result;

using (var streamToReadFrom = response.Content.ReadAsStreamAsync().Result)
{
    using (var streamToWriteTo = File.Open("C:\DownlodedFile.dat", FileMode.Create))
    {
        streamToReadFrom.CopyTo(streamToWriteTo);
    }
}


Object name: 'System.Net.Sockets.NetworkStream'. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
  at System.Net.WebConnection.BeginRead (System.Net.HttpWebRequest request, System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.AsyncCallback cb, System.Object state) [0x0002b] in <630c0f79573e4170a5c7a506b24194ce>:0 
  at System.Net.WebConnectionStream.BeginRead (System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.AsyncCallback cb, System.Object state) [0x0017d] in <630c0f79573e4170a5c7a506b24194ce>:0 
  at System.Net.WebConnectionStream.Read (System.Byte[] buffer, System.Int32 offset, System.Int32 size) [0x00007] in <630c0f79573e4170a5c7a506b24194ce>:0 
  at System.IO.Stream.InternalCopyTo (System.IO.Stream destination, System.Int32 bufferSize) [0x00012] in <5d6981f842764a0d98ada564ac3cd92e>:0 
  at System.IO.Stream.CopyTo (System.IO.Stream destination) [0x00084] in <5d6981f842764a0d98ada564ac3cd92e>:0 
  at (wrapper remoting-invoke-with-check) System.IO.Stream:CopyTo (System.IO.Stream)
Comment 1 Marek Safar 2017-09-08 22:59:42 UTC
I cannot reproduce the issue locally using the following repro.


using System;
using System.IO;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace Test1234
{
	class MainClass
	{
		public static void Main(string[] args)
		{
			var httpClient = new HttpClient ();
			var response = httpClient.GetAsync ("https://en.wikipedia.org/wiki/Main_Page", HttpCompletionOption.ResponseHeadersRead).Result;

			using (var streamToReadFrom = response.Content.ReadAsStreamAsync ().Result) {
				using (var streamToWriteTo = new MemoryStream ()) {
					streamToReadFrom.CopyTo (streamToWriteTo);
				}
			}
		}
	}
}


In order to investigate the issue further can you please attach a reproduction project and steps to reproduce this issue? For help on writing a bug report, please see our guide on this topic:

https://bugzilla.xamarin.com/page.cgi?id=bug-writing.html

Some of your next steps would be:

1. Including a sample project or steps to reproduce this problem
2. Your Version Information
3. Your expected results and actual results

Thank you!
Comment 2 Andy 2017-09-13 15:00:20 UTC
I've found the problem. In my application there is a call to the HttpClient and the returned HttpResponseMessage is passed to another method. This leaves the HttpClient object ready for disposing. However the second call would try and read the steam when the HttpClient had been disposed. 

The example below runs fine under Windows and I will change my code so that the HttpClient is not immediately disposed. I'm happy for this to be closed but any thoughts?


using System.IO;
using System.Net.Http;

namespace MonoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var response = GetMedia();

            StoreResponseData(response);
        }

        private static HttpResponseMessage GetMedia()
        {
            using (var httpClient = new HttpClient())
            {
               return httpClient.GetAsync("https://en.wikipedia.org/wiki/Main_Page", HttpCompletionOption.ResponseHeadersRead).Result;
            }
        }

        private static void StoreResponseData(HttpResponseMessage response)
        {
            using (var streamToReadFrom = response.Content.ReadAsStreamAsync().Result)
            {
                using (var streamToWriteTo = new MemoryStream())
                {
                    streamToReadFrom.CopyTo(streamToWriteTo);
                }
            }
        }
    }
}
Comment 3 Marek Safar 2017-09-14 10:14:05 UTC
I can reproduce it now

Note You need to log in before you can comment on or make changes to this bug.