2017-10-17 12 views
0

J'ai trouvé que mon application Android Xamarin tourne lentement, j'ai donc ajouté du code asynchrone/attente pour améliorer les performances. Je voulais exclure mes appels d'API du thread de l'interface utilisateur. Je pensais que ce serait une opportunité parfaite d'utiliser async/await. Donc, j'ai ajouté async à la signature de la fonction et enveloppé la tâche autour de mon type de valeur de retour. Ensuite, j'ai mis à jour l'appel RestSharp GET avec "wait client.ExecuteTaskAsync". Une fois cela fait, j'ai trouvé que j'avais besoin de mettre à jour mon appel à la fonction GetCustInfo. J'ai simplement besoin d'ajouter .Result à la fin de l'appel et il n'a montré aucune erreur. Le problème est qu'il se bloque sur l'appel à GetCustInfo et ne fonctionne tout simplement pas.Xamarin Android app - Problèmes d'ajout asynchrone/attente à un appel API pour améliorer les performances

Qu'est-ce que je fais mal ici?

public async Task<List<CustInfo>> GetCustInfo(string strBranchNumber, string dblCurrentXCoordinate, string dblCurrentYCoordinate) 
    { 
     if (this.strBearerToken == string.Empty) 
     { 
      throw new ArgumentException("No Bearer Token Found"); 
     } 

     try 
     { 
      var restUrl = this.strCustomerInfoAPIURL; 
      var uri = new Uri(string.Format(restUrl, string.Empty)); 

      var client = new RestClient(uri); 
      var request = new RestRequest(Method.GET); 
      request.AddHeader("Authorization", "bearer " + this.strBearerToken); 
      request.AddParameter("intBranchNumber", strBranchNumber); 
      request.AddParameter("intZipCode", this.strZipCode); 
      request.AddParameter("intCustomerType", this.strCustomerType); 
      request.AddParameter("intMinTotalAmount", this.strMinRevenue); 
      request.AddParameter("dblCurrentXCoordinate", dblCurrentXCoordinate); 
      request.AddParameter("dblCurrentYCoordinate", dblCurrentYCoordinate); 
      request.AddParameter("bolGetLocation", true); 

      var response = await client.ExecuteTaskAsync(request);     
      return JsonConvert.DeserializeObject<List<CustInfo>>(response.Content).OrderBy(x => x.ApproxDistance).ToList(); 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

Alors ce qui se passe est quand je l'appelle la async/Attendent fonction de mon OnCreate il arrête juste quand je tente d'appeler customer.GetCustomerInfo().

protected override void OnCreate(Bundle bundle) 
    { 
     .... 

      this.tableItems = customer.GetCustInfo(
       "xxxxxxx", 
       this.currentLocation.Latitude.ToString(), 
       this.currentLocation.Longitude.ToString()).Result; 
      this.listView.Adapter = new ListOfLocationAdapter(this, this.tableItems); 

    } 
+1

donc il se comporte comme un appel bloquant. utilisez un événement différent dans le cycle de vie de l'interface utilisateur pour le déclencher et appelez-le en utilisant la syntaxe 'await'. – dlatikay

+0

Pouvez-vous donner un exemple de ce que vous voulez dire? Tous les événements du cycle de vie de l'interface utilisateur ne feront-ils pas partie du fil de l'interface utilisateur? –

+0

J'ai fait quelques recherches et trouvé que je devais ajouter mon appel à custinfo dans l'appel OnStart qui est dans le cycle de vie. Ça fonctionne. Merci pour le conseil! –

Répondre

0

Modifier l'appel à

this.tableItems = await customer.GetCustInfo(.. 

et faites-nous .. Dans la ligne suivante, vous utilisez le résultat de l'appel pas attendu, il serait évidemment bloque, quelle que soit l'accident:

OnCreate se trouve sur le thread d'interface utilisateur de l'action que vous entrez, et non asynchrone, et vous n'attendez pas l'appel de GetCustInfo.
+0

il suffit de créer une fonction async avec le contenu complet de votre OnCreate et appelez-le sans attendre, maintenant que l'accélérer et faire ce que vous voulez. –