IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinRT Discussion :

Methode asynchrone qui bloque l'UI


Sujet :

WinRT

  1. #1
    Membre habitué Avatar de poussinphp
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    428
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 428
    Points : 176
    Points
    176
    Par défaut Methode asynchrone qui bloque l'UI
    Bonjour,

    Je cherche à remplir une gridview groupé lors du chargement de la page.

    Dans le constructeur de mon viewmodel, je lance une méthode d'initialisation qui appel chaque méthode pour remplir catégorie par catégorie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
            public async void Init()
            {
                HomeCategory cat = new HomeCategory("Mes Fichiers", new List<HomeItemModel>());
                GroupedItems.Add(cat);
                await FillFileData(cat);
            }
     
            private async Task FillFileData(HomeCategory cat)
            {
                //await Task.Delay(200);
                List<ItemInfo> sqlItems = await SqlManager.Instance.GetFilesAsync();
                foreach (Item item in sqlItems)
                {
                    cat.Items.Add(new HomeItemModel(item));
                  //  await Task.Delay(200);
                }
           }
    Vous constaterez que j'ai mis des Delas commentés. J ne comprend pas pourquoi mais si je les met, la page s'affiche, je peux scroller tranquillement et ça remplit 1 à 1 les éléments. Si je ne les mets pas, je constate que l'UI fige, pourtant, c'est une méthode asynchrone.

    Je comprend pas ce qu'il se passe et je suis bloqué dessus, auriez-vous une idée d’où peux bien provenir le problème?

  2. #2
    Membre expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    HomeCategory c'est quoi? Un contrôle ? Il y a combien d'éléments dans sqlItems ?

    Même si la méthode est asynchrone, elle ne sera asynchrone que pour les méthodes qui sont awaitable, c'est à dire le GetFileAsync. Le reste tourne en synchrone.

    A mon avis ce qui se passe c'est qu'il y a un traitement qui se fait quelque part dans le Items.Add dans la boucle (Probablement un datatemplate XAML qui doit être crée). Quand tu mets le Delay, vu que c'est asynchrone, le thread UI a bien le temps de faire ce traitement. Quand le Delay n'est pas là, la boucle tourne très vite et le thread UI passe tout son à ajouter les éléments et donc n'a plus le temps de rafraîchir l'écran.
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 66
    Points : 116
    Points
    116
    Par défaut
    Je confirme la réponse ci-dessus.

    En fonction du nombre d'objets à ajouter dans la liste tu auras plusieurs solutions :
    - Tu peux faire un AddRange de tout tes objets si tu n'en a pas trop
    - Tu peux les ajouter 20 par 20 et mettre à Delay après sinon si tu en a beaucoup

    D'autres variantes sont possibles comme le fait de ne requêter que ce que tu as besoins et de l'ajouter à la liste.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    En effet, Olivier a totalement raison.

    Et puis il faudrait que l'on sache : que sont les objets "HomeCategory", "HomeItemModel" et "GroupedItems"? Sont-ils liés à des éléments d'IHM? Cela est important pour savoir comment faire cette optimisation...

  5. #5
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2007
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 677
    Points : 2 137
    Points
    2 137
    Par défaut
    HomeCategory est très certainement un control utilisateur, le fait de remplir sa propriété Items (qui doit certainement être bindée quelque part) dans une méthode asynchrone va faire appel au Dispatcher (qui est en charge de la gestion des évènements de mise à jour de l’UI). Faire appel à ce Dispatcher de manière "bourrin" (à de nombreuses reprises dans un très court laps de temps) va le noyer littéralement ; va en résulter un blocage de l’UI le temps qu’il dépile tous les évènements de mise à jour qu’il a reçus. C’est d’ailleurs la raison pour laquelle le Task.Sleep() dans ta boucle fluidifie l’affichage ; Le Dispatcher profite de ce laps de temps pour dépiler les notifications en attente, et évite ainsi la saturation, et donc le blocage de l’UI.

    Noyer le Dispatcher, dans le meilleurs des cas ça fait ramer l’UI (tu en fais les frais), dans le pire des cas, tu obtiens une surconsommation de mémoire qui fait tout planter.

    Idéalement il faut limiter le plus possible les appels au Dispatcher (pagination, temporisation, etc...).
    Le WIP de The last bastion, mon projet de jeu-vidéo (un TD en 3D)

    Mon portfolio / Ma page fb

Discussions similaires

  1. Spyware qui bloque le fond d'écran Windows
    Par akli_agha dans le forum Sécurité
    Réponses: 6
    Dernier message: 02/02/2006, 17h16
  2. pc qui bloque et message du BIOS
    Par ouldfella dans le forum Ordinateurs
    Réponses: 4
    Dernier message: 13/10/2005, 14h22
  3. Réponses: 3
    Dernier message: 22/07/2005, 15h16
  4. [MFC] fonction ReadFile qui bloque
    Par r0d dans le forum MFC
    Réponses: 9
    Dernier message: 15/04/2005, 13h21
  5. Réponses: 6
    Dernier message: 21/03/2005, 13h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo