1

私はこの問題をしばらく苦労していました。ここで私の質問をしてください。したがって、状況は次のとおりです。Xamarin.AndroidイベントハンドラデッドロックからWebAPIを非同期で呼び出す

WebAPIとXamarin.AndroidアプリケーションとIdentityServer4実装があります。 Xamarin.AndroidアプリはWebAPIを呼び出して、検索に基づいてユーザーのリストを取得する必要があります。これは、TextChangedイベントハンドラで非同期呼び出しによって行われます。何が起こるかは、WebAPIへの呼び出しが待たれても返されず、ある時点で取り消されるということです。私はConfigureAwait(false)を使って試してみました。私はイベントハンドラメソッドを非同期voidにしました。私は同様の問題についていくつかの他の質問を読んできました。

を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)に関係なくそこに存在します。私はこの記事を読んだ後に追加しました:[リンク](http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) –

+0

それは、非同期と呼び出しを混在させます。これまであなたが示したコードはそれを持っていないようです。 – Nkosi

答えて

0

さて、問題を修正したかどうかは分かりませんが、ここで私は何をしましたか?再配置する前に手動でエミュレータからアプリケーションをアンインストールすると問題が解決された同様の問題のStackOverflow質問がありました。また、ConfigureAwait(false)コールを削除しました。そして、突然、すべてが動いています。どのように起こったのかは分かりませんが、ここではアプリを手動でアンインストールし、ConfigureAwait(false)を指定せずにAPIを呼び出すとそれが行われました。

関連する問題