1

我一直在努力解决这个问题一段时间,现在是时候让我在这里问我的问题。所以,这里的情况:从Xamarin.Android事件处理程序异步调用WebAPI

我有一个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接口,而不是添加事件处理程序,并更改代码,所以我不使用单独的方法,而是使用匿名代理 - 我在某些地方读过这些可能证明是一个问题。

我真的希望你们中的一些人能够帮助我解决这个问题,并让我明白如何正确地进行这种异步调用。

此致敬礼。

+0

从'GetStringAsync'中删除'.ConfigureAwait(false);'会发生什么? – Nkosi

+0

我试图解决这个问题 - 它没有改变任何东西。无论是否存在ConfigureAwait(false),问题都在那里。我在阅读这篇文章后添加了它:[link](http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) –

+0

这意味着在调用堆栈中的某个地方混音异步和阻止呼叫。到目前为止,你所显示的代码似乎没有。 – Nkosi

回答

0

好吧,所以我不确定是什么修复了这个问题,但这是我做了什么 - 还有另一个StackOverflow问题,类似的问题是在重新部署它之前手动从模拟器中卸载应用程序解决问题。我还删除了ConfigureAwait(false)调用。突然间,一切正常。不知道它是如何发生的,但在这里 - 手动卸载应用程序并在没有ConfigureAwait(false)的情况下调用API来做到这一点。