HttpClient 上的 ObjectDisposedException
ObjectDisposedException on HttpClient
我有一个包含多个 API 调用的 Windows 通用项目。
一种方法拒绝工作,即使我的其他调用像这样完美地工作。
我已经尝试了 using
关键字,认为它可以解决问题。
函数:
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;
}
}
}
编辑
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;
}
}
}
堆栈跟踪
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()
ObjectDisposedException
被抛出,因为您在 req.Content.ReadAsStringAsync()
完成之前处理 HttpRequestMessage
和 HttpClient
。
注意req.Content.ReadAsStringAsync()
是一个异步方法。在处理 HttpClient
.
之前,您需要等待它完成
还有,你好像在req.Content
中调用ReadAsStringAsync
,应该是response.Content
吧?
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;
}
几乎没有理由在处理async/await时使用ContinueWith
。所有这些都由编译器为您完成。
您正在访问请求内容,而不是响应。
这个
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();
抛出 ObjectDisposedException
的实际原因是 HttpClient
在完成请求后立即处理 Content
。看看 docs.
因此,如果您需要阅读 Request
的内容,例如在测试中,请确保在 之前 调用 SendAsync
。
我有一个包含多个 API 调用的 Windows 通用项目。
一种方法拒绝工作,即使我的其他调用像这样完美地工作。
我已经尝试了 using
关键字,认为它可以解决问题。
函数:
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;
}
}
}
编辑
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;
}
}
}
堆栈跟踪
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()
ObjectDisposedException
被抛出,因为您在 req.Content.ReadAsStringAsync()
完成之前处理 HttpRequestMessage
和 HttpClient
。
注意req.Content.ReadAsStringAsync()
是一个异步方法。在处理 HttpClient
.
还有,你好像在req.Content
中调用ReadAsStringAsync
,应该是response.Content
吧?
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;
}
几乎没有理由在处理async/await时使用ContinueWith
。所有这些都由编译器为您完成。
您正在访问请求内容,而不是响应。
这个
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();
抛出 ObjectDisposedException
的实际原因是 HttpClient
在完成请求后立即处理 Content
。看看 docs.
因此,如果您需要阅读 Request
的内容,例如在测试中,请确保在 之前 调用 SendAsync
。