Portage RP : Dispatcher.Invoke -> Dispatcher.RunAsync

Answered Portage RP : Dispatcher.Invoke -> Dispatcher.RunAsync

  • mercredi 27 juin 2012 08:09
     
      A du code

    Salut à tous,

    J'ai trouvé un tutoriel super sympathique sur une appli Open Data ici.

    Malheureusement celle-ci est encore en CP. J'essaye donc de porter tout ça sur la RP.

    Il y a une partie que je ne sais pas comment mettre à jour.

    Version CP : 

    Dispatcher.Invoke(CoreDispatcherPriority.Normal, (sender, e) =>
                {
                   var newData = e.Context as IEnumerable<CartePostaleModel>;
                   foreach (var item in newData)
                   {
                      _catalog[_currentPageNumber].Add(item);
                      itemGridView.Items.Add(item);
                   }

    A priori il faut remplacer Dispatcher.Invoke par Dispatcher.RunAsync. Or le délégué ne contient pas de paramètres.

    => On ne peut pas faire un newData = e.Context

    Du coup je me demandais par quoi je pouvais remplacer le e.Context.

    Quelqu'un a une idée?

    Merci d'avance!


    Christophe H.

Toutes les réponses

  • jeudi 28 juin 2012 07:35
     
     Traitée A du code

    L'équipe OGDI France en charge de l'application Open Data, vient de me répondre par mail concernant ce problème de portage, et voici leur réponse, avec le code associé : 

    Avec la migration en Windows 8 Release Preview, la méthode Dispatcher.Invoke est devenue asynchrone et remplacée par Dispatcher.RunAsync afin de ne pas bloquer l’interface principale lors de traitements couteux.

     

    La solution consiste donc à utiliser la TPL (Task Parallel Library) maintenant incluse dans le Framework .NET 4.5 pour gérer de l’asynchrone. L’avantage de la TPL est qu’elle simplifie la gestion de l’asynchrone notamment sur l’accès aux variables dans différents threads.

     

    En assumant que le code extrait de votre question provient de la méthode LoadNextPage(), le code suivant devrait résoudre votre problème :

                    Task t = new Task(new Action(async () =>
                    {
                        bool loadMore = true;
                        List<CartePostaleModel> cartes = new List<CartePostaleModel>();
                        // Chargement des données par groupe de 5 pour une fluidité maximale.
                        while (_ogdiConsumer.LoadNextDataChunk(5, cartes).Result == true && loadMore == true)
                        {
                            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                try
                                {
                                    itemGridView.Items.Remove(itemGridView.Items.First(x => (x as CartePostaleModel).commune == "Afficher plus"));
                                }
                                catch { }
     
                                var newData = cartes;
                                foreach (var item in newData)
                                {
                                    App._catalog[_currentPageNumber].Add(item);
                                    itemGridView.Items.Add(item);
                                }
                                // On se limite à 20 éléments par page
                                if (itemGridView.Items.Count % 20 == 0)
                                {
                                    loadMore = false;
                                    _currentPageNumber++;
                                    itemGridView.Items.Add(new CartePostaleModel() { commune = "Afficher plus", fichier = "ms-appx:/Images/Icons/plus.png" });
                                }
                            });
                            cartes.Clear();
                        }
                        _isLoading = false;
                    }));
     
                    Task final = t.ContinueWith(async (val) =>
                    {
                        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            Random rand = new Random();
                            if (itemGridView.Items.Count > 0)
                            {
                                var item = itemGridView.Items[rand.Next(0, itemGridView.Items.Count - 1)] as CartePostaleModel;
                            }
     
                        });
                    });
     
                    t.Start();
    

    Merci à eux en tout cas, ils sont super efficaces! Il n'y a plus qu'à tester tout ça!


    Christophe H.