我想从异步方法内部调用异步Web服务方法,并使用WPF窗口来询问用户的用户名和密码。
守则看起来与此相似:
private async Task GetUsers()
{
List<User> users = new List<User>();
using (var client = new HttpClient())
{
var authenticationWindow = new AuthenticateWindow();
authenticationWindow.ShowDialog();
//... Code to get the token ...
var token = "myToken";
client.BaseAddress = new Uri("http://localhost:56057/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
var response = await client.GetAsync("api/users/");
if (response.IsSuccessStatusCode)
{
users = await response.Content.ReadAsAsync<List<User>>();
}
else if (response.StatusCode == HttpStatusCode.Unauthorized)
{
throw new UnauthorizedAccessException();
}
}
foreach(var user in users)
{
}
}
如果我执行此代码,我会收到以下异常:
An unhandled exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll
调用client.GetAsync(“api / users /”)时会发生这种情况。它可能与上下文切换有关,因为我打开了窗口。
我该如何解决这个问题?
调用堆栈只显示“外部代码”。
如果我删除以下两行,一切正常:
var authenticationWindow = new AuthenticateWindow();
authenticationWindow.ShowDialog();
答案 0 :(得分:2)
您正在实例化一个UI元素并在服务范围内使用,请尝试将这两个元素彼此分开。听起来你需要在AuthenticateWindow
中使用这种逻辑来请求用户,也许是在Loaded
事件中:
// Safe UI entry point for async work, i.e.; event handler.
async void OnLoaded(object sender, RoutedEventArgs e)
{
var users = await GetUsersAsync();
// Take action on the user's from the API.
}
然后让GetUsers
(更适合更改为GetUsersAsync
)只关注使用HttpClient
和相应的API,实现并返回List<User>
,如下所示:< / p>
async Task<List<User>> GetUsersAsync()
{
List<User> users = new List<User>();
using (var client = new HttpClient())
{
//... Code to get the token ...
var token = "myToken";
client.BaseAddress = new Uri("http://localhost:56057/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
var response = await client.GetAsync("api/users/");
if (response.IsSuccessStatusCode)
{
users = await response.Content.ReadAsAsync<List<User>>();
}
else if (response.StatusCode == HttpStatusCode.Unauthorized)
{
throw new UnauthorizedAccessException();
}
}
return users;
}