Why this use of HttpClient gives me "Unable to access the remote object." mistake?

I simplified the code a bit, but basically it kept giving me "Unable to access the remote object." a mistake, and I can’t understand why?

I simultaneously perform several tasks that perform a GET, then parse some HTML, then perform a POST depending on the results of the GET.

The method this code is in returns an event object with the results, so I don’t think I can use it because the method should return void?

loginHTMl = loginPostResult.Content.ReadAsStringAsync () The result is the line that creates the error

foreach (Account accountToCheck in eventToCheck.accountsToRunOn) { Task.Run(() => { HttpClientHandler handler = new HttpClientHandler(); CookieContainer cookies = new CookieContainer(); handler.CookieContainer = cookies; using (var client = new HttpClient(handler)) { ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; client.Timeout = new TimeSpan(0, 0, 3); client.DefaultRequestHeaders.Add("Keep-Alive", "false"); HttpResponseMessage response = client.GetAsync("https://test.com", HttpCompletionOption.ResponseContentRead).Result; string html = response.Content.ReadAsStringAsync().Result; var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("test[username_or_email]", accountToLogIn.accountHandle), new KeyValuePair<string, string>("test[password]", accountToLogIn.accountPassword) }); var loginPostResult = client.PostAsync("https://test.com/login", content).Result; loginHTMl = convertToUTF8(loginPostResult.Content.ReadAsStringAsync().Result); } }); } 

Stacktrace

 System.IO.IOException occurred HResult=-2146232800 Message=Unable to read data from the transport connection: Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'.. Source=System StackTrace: at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) InnerException: HResult=-2146232798 Message=Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'. ObjectName=System.Net.Sockets.Socket Source=System StackTrace: at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode) at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) InnerException: 
+8
source share
2 answers

Well, after a little research, I found the problem. HttpClientHandler will be deleted after the first request. You need to specify that your system does not delete the handler.

Change the usage to add false to the constructor.

 using (var client = new HttpClient(handler, false)) { } 
+16
source

It is good practice to reuse an instance of the HttpClientHandler to prevent disposal.

Also, personally, I prefer a clearer syntax with minimizing Task.Result calls.

 // single setup of client handler HttpClientHandler handler = new HttpClientHandler(); var tasks = eventToCheck.accountsToRunOn.Select(async () => { // ... using (var client = new HttpClient(handler, false)) // pass false to prevent Disposing { // ... var html = await response.Content.ReadAsStringAsync(); // ... return loginHtml; } }); // get array of results string[] loginsHtml = await Task.WhenAll(tasks); 
+3
source

All Articles