2 votes

Comment utiliser correctement async/await pour afficher l'ActivityIndicator de Xamarin Forms ?

J'ai un code qui est exécuté lorsqu'un ListView est sélectionné. Étant donné que l'exécution de ce code peut prendre un temps considérable, je veux afficher un message d'avertissement. ActivityIndicator pendant qu'il fonctionne.

J'ai lu de nombreux articles sur le thème de l'éducation. ActivityIndicator et je crois que je l'ai configuré correctement. Je suis presque sûr que mon problème est dû au fait que le code en cours d'exécution bloque le thread de l'interface utilisateur, puisque l'interface se fige complètement pendant le processus.

J'ai travaillé sur toutes les variantes que j'ai pu trouver pour l'utilisation d'async/await, sans succès, donc je suppose que je fais toujours quelque chose d'incorrect.

Voici mon code :

private ListItem selectedList;
public ListItem SelectedList
{
    get
    {
        return selectedList;
    }
    set
    {
        if (selectedList != value)
        {
            var oldValue = selectedList;
            selectedList = value;
            buildThisList();
        }
    }
}

private async void buildThisList()
{
    StatusBarIsVisibile = true; 
    ThisList = Task.Run(async () =>
    {
        return await buildBnBList(SelectedList, selectedLocation, 
                         thisYearList.ListId)
                         .ConfigureAwait(false);
    }).Result;  // 1.8 seconds
    StatusBarIsVisibile = false;
    ThisList.MainVM = this;
    ThisList.BuildView();
    PIShowListHeaderText = SelectedList.Title.Trim();
}

private async Task<BnBList> buildBnBList(ListItem pSelectedList, State pselectedLocation, int pListId)
{
    BnBList newList = new BnBList(pSelectedList, pselectedLocation, pListId);
    List<BirdsnBflysMaster> bbfList = 
         App.BnBRepo.GetBirdsnBflys(selectedList.ListType); // 1.3 seconds
    Lists parentList = App.BnBRepo.GetAList(SelectedList.ListId); // .5 seconds
    BnBItem newBnBItem;
    foreach (BirdsnBflysMaster bbf in bbfList) // .4 seconds
    {
        newBnBItem = new BnBItem(parentList, bbf, selectedLocation, newList, thisYearList.ListId);
        newList.ListAll.Add(newBnBItem);
        if (newBnBItem.ListTypeID == "Bird")
        {
            ...
        }
        else
        {
            ...
        }
    }            
    return newList;
}

Donc :

  • buildThisList est appelé lorsque le SelectedList les changements de propriété.
  • buildThisList appelle buildBnBList ce qui est un processus qui prend du temps.
  • buildBnBList ne contient rien qui soit fait de manière asynchrone.
  • StatusBarIsVisible est lié à la fois à IsVisible y IsRunning de la ActivityIndicator .

Comment puis-je coder cela pour que l'exécution buildBnBList ne bloque pas le thread de l'interface utilisateur ?

4voto

Nkosi Points 95895

Oui vous un blocage de mélange ( .Result ) avec du code asynchrone qui risque de provoquer des blocages. async void devrait être évité, sauf dans un gestionnaire de pair.

Alors, pourquoi ne pas le faire ?

Créez un événement et un gestionnaire d'événement.

public event EventHandler ListSelected = delegate { }

cela devrait maintenant vous permettre de créer un gestionnaire d'événement

private async void OnListSelected(object sender, EventArgs e) {
    StatusBarIsVisibile = true; 
    ThisList = await buildBnBList(SelectedList, selectedLocation, thisYearList.ListId);

    StatusBarIsVisibile = false;
    ThisList.MainVM = this;
    ThisList.BuildView();
    PIShowListHeaderText = SelectedList.Title.Trim();
}

Vous vous inscrivez évidemment à l'événement (au début du cycle de vie bien sûr)

this.ListSelected += OnListSelected;

et augmenter l'événement si nécessaire

private ListItem selectedList;
public ListItem SelectedList {
    get {
        return selectedList;
    }
    set {
        if (selectedList != value) {
            var oldValue = selectedList;
            selectedList = value;
            OnListSelected(this, EventArgs.Empty);
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X