【发布时间】:2017-08-11 12:51:09
【问题描述】:
我已经为这个问题苦苦挣扎了一段时间,现在是时候在这里提出我的问题了。所以,情况是这样的:
我有一个 WebAPI、一个 Xamarin.Android 应用程序和一个 IdentityServer4 实现。 Xamarin.Android 应用需要调用 WebAPI 以获取基于搜索的用户列表。这是通过 TextChanged 事件处理程序中的异步调用完成的。发生的情况是,当等待对 WebAPI 的调用时,它永远不会返回,并且在某些时候任务会被取消。我已经尝试使用 ConfigureAwait(false),我已经使事件处理程序方法异步无效,我已经阅读了关于类似问题的其他几个问题 - 没有一个选项对我有用。但这里有一些代码让你了解我在做什么:
TextChanged 处理程序:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.SearchPeopleLayout);
this.searchUsersElement = FindViewById<EditText>(Resource.Id.searchUsersField);
this.usersListElement = FindViewById<ListView>(Resource.Id.usersSearchResult);
using (var scope = App.Container.BeginLifetimeScope())
{
this.apiClient = App.Container.Resolve<IUsersApiClient>();
}
this.searchUsersElement.TextChanged += SearchUsersElement_TextChanged;
}
public async void SearchUsersElement_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
var length = e.Start + e.AfterCount;
if (length <= MinUsernameLength)
{
return;
}
var searchName = string.Join(string.Empty, e.Text);
var users = await this.apiClient.GetUsers(searchName, Persistor.ApiClient);
RunOnUiThread(() =>
{
var usersAdapter = new UsersAdapter(this, users.ToList());
this.usersListElement.Adapter = usersAdapter;
});
}
这是 UsersApiClient 的实现:
public async Task<IEnumerable<UserModel>> GetUsers(string username, HttpClient client)
{
try
{
var content = await client.GetStringAsync($"{apiUrl}/users?name={username}").ConfigureAwait(false);
var result = JsonConvert.DeserializeObject<IEnumerable<UserModel>>(content);
return result;
}
catch (Exception ex)
{
throw ex;
}
}
死锁发生在 GetStringAsync() 调用上。我已经测试了它通过 Postman 拨打的电话,它给了我正确的回应。只有我还没有尝试过的事情是实现 ITextWatcher 接口而不是添加事件处理程序,并更改代码所以我不使用单独的方法而是使用匿名委托 - 我在某些地方读到了可能证明是一个问题。
我真的希望你们中的一些人能帮助我解决这个问题,让我了解如何正确地执行此类异步调用。
最好的问候。
【问题讨论】:
-
从
GetStringAsync中删除.ConfigureAwait(false);会发生什么? -
我把它放在那里是为了解决这个问题——它不会改变任何东西。无论 ConfigureAwait(false) 是否存在,问题都存在。看了这篇文章我加了:link
-
这意味着调用堆栈中的某些位置混合了异步和阻塞调用。到目前为止,您显示的代码似乎没有。
-
这应该就是全部了——我已经用 TextChanged 事件处理程序设置和包含异步调用的 UserApiClient 为你提供了 onCreate() 覆盖——这就是全部。我猜我在调用 API 的整个异步 void 事件处理程序中遗漏了一些东西。
-
创建时是否立即调用文本更改?可能是每次您键入它都会调用处理程序,并且与受限制的调用相比,一次调用过多
标签: c# asp.net-web-api xamarin.android event-handling async-await