2016-04-18 1 views
8

Я немного упростил код, но в основном это продолжало давать мне «Невозможно получить доступ к удаленному объекту». ошибка, и я не могу понять почему?Почему это использование HttpClient дает мне «Не удается получить доступ к удаленному объекту». ошибка?

У меня одновременно выполняется несколько задач, которые выполняют GET, затем анализируют некоторый HTML, затем выполняют POST в зависимости от результатов GET.

Метод, в котором находится этот код, возвращает объект события с результатами, поэтому я не думаю, что могу использовать его, потому что метод должен возвращать void?

loginHTMl = loginPostResult.Content.ReadAsStringAsync(). Результат является линией, которая производит ошибку

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: 
+0

Какая строка дает вам это исключение? Опубликуйте всю трассировку стека в своем вопросе. – CathalMF

+0

Можете ли вы опубликовать фактическую трассировку стека исключения, которое вы видите., – CathalMF

+0

Я редактировал вопрос, надеюсь, что немного помогает, дайте мне знать, что еще я могу добавить :-) – jamie

ответ

16

ОК после небольшого исследования я нашел проблему. HttpClientHandler будет удален после первого запроса. Вам нужно указать, чтобы ваша система не удаляла обработчик.

Измените использование, чтобы добавить false в конструктор.

using (var client = new HttpClient(handler, false)) 
{ 

} 
+0

Странно, я установил это, но он, похоже, не имеет значения – willem

3

Это хорошая практика повторного использования экземпляра HttpClientHandler для предотвращения утилизации.

Также лично я предпочитаю более четкий синтаксис с минимизацией вызовов Task.Result.

// 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); 
Смежные вопросы