2015-03-31 22 views
5

Birden çok API çağrısı içeren bir Windows Evrensel Projesi var. Bir yöntem, diğer aramalarımın bu şekilde mükemmel şekilde çalışması için çalışma yapmayı reddediyor. Sorunu çözeceğini düşündüğüm using anahtar kelimesini denedim.HttpClient üzerinde ObjectDisposedException

işlevi: HttpRequestMessage ve HttpClient önce bertaraf çünkü

public async Task<User> GetNewUser(string user_guid, OAuthTokens OAuth) 
{ 
    String userguidJSON = VALIDJSON_BELIEVE_ME; 
    using (var httpClient = new HttpClient()) 
    { 
     httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Encrypt(OAuth.Accesstoken)); 

     using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data")) 
     { 
      req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json"); 
      await httpClient.SendAsync(req).ContinueWith(respTask => 
      { 
       Debug.WriteLine(req.Content.ReadAsStringAsync()); //Error is thrown ono this line 
      }); 
      return null; 
     } 
    } 
} 

DÜZENLEME

public async Task<User> GetNewUser(string user_guid, OAuthTokens OAuth) 
{ 
    String userguidJSON = VALIDJSON_BELIEVE_ME; 
    using (var httpClient = new HttpClient()) 
    { 
     httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Encrypt(OAuth.Accesstoken)); 

     using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data")) 
     { 
      req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json"); 
      await httpClient.SendAsync(req); 
      var result = await req.Content.ReadAsStringAsync(); //Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'. 
      Debug.WriteLine(result); 
      return null; 
     } 
    } 
} 

StackTrace

at System.Net.Http.HttpContent.CheckDisposed() 
    at System.Net.Http.HttpContent.ReadAsStringAsync() 
    at Roadsmart.Service.RoadsmartService.<GetNewUser>d__2e.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at Roadsmart.ViewModel.SettingsPageViewModel.<SetNewProfilePicture>d__1e.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state) 
    at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore() 
+1

Neden "ContinueWith" ile "bekliyor" u karıştırıyorsunuz? –

+0

Neden "ContinueWith" kullanıyorsunuz? Async/wait ile çalışırken 'ContinueWith' kullanmanız gerekmez. –

cevap

8

ObjectDisposedException atılır req.Content.ReadAsStringAsync() bitirir.

req.Content.ReadAsStringAsync()'un eşzamansız bir yöntem olduğunu unutmayın. HttpClient'u atmadan önce tamamlanmasını beklemeniz gerekir.

Ayrıca, req.Content numaralı telefondan ReadAsStringAsync numaralı telefonu arıyor olmalısınız, response.Content olmalıdır?

using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data")) 
{ 
    req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json"); 
    var response = await httpClient.SendAsync(req); 
    var result = await response.Content.ReadAsStringAsync();//await it 
    Debug.WriteLine(result); 
    return null; 
} 

Neredeyse zaman uyumsuz ile uğraşırken ContinueWith kullanmak için hiçbir neden yoktur/bekliyor. Tüm bunlar derleyici tarafından sizin için yapıldı.

+0

Tamam, ipucu için teşekkürler, ancak var sonuçtan sonra hata şimdi atıldı = ... Atılan bir nesneye erişilemiyor. Nesne adı: 'System.Net.Http.StringContent'. – tim

+0

@SeaSharp Şimdi istisna nedir? Stacktrace'i ve güncellenmiş kodunuzu gönderin. –

+0

Bitti. Yardımın için şimdiden teşekkürler. – tim

4

İstek alanına değil, İstek'e erişiyorsunuz.

Bu

await httpClient.SendAsync(req); 
var result = await req.Content.ReadAsStringAsync(); //Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'. 

var response = httpClient.SendAsync(req); 
var result = await response.Content.ReadAsStringAsync(); 
+0

Sadece çok geç :) – tim

4

HttpClient hemen tamamlanmış isteğinden sonra Content elden çünkü atılır ObjectDisposedException olan gerçek nedeni olmalıdır. docs'a bir göz atın.

Yani testlerde örneğin bir Request 'ın içeriğini okumak gerekirse,SendAsync çağırmadan önce okumak için emin olun.

+0

Ben de bu problemi gördüm.Aynı İçeriği iki kez göndermeyi denerseniz ve tekrar denerseniz (bir zaman aşımı ya da benzer bir şekilde), bir ObjectDisposedException alırsınız. Bu, başvuru kaynağında düzeltilmiş gibi görünüyor: https://github.com/ dotnet/corefx/blob/master/src/System.Net.Http/src/Sistem/Net/Http/HttpClient.cs # L517 (yine de aynı sorunu System.Net.Http, Version = kullanarak görüyorum) 4.0.0.0) –