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來做到這一點。

相關問題