85 votes

La bonne façon d'obtenir le CoreDispatcher dans une application du Windows Store

Je suis en train de créer une application Windows Store, et j'ai du code qui doit être affiché dans le fil de discussion de l'interface utilisateur.

Pour cela, j'aimerais récupérer le CoreDispatcher et l'utiliser pour poster le code.

Il semble qu'il y ait plusieurs façons de procéder :

// First way
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher;

// Second way
Window.Current.Dispatcher;

Je me demande laquelle est la bonne ou si les deux sont équivalentes.

154voto

MAXE Points 1955

C'est la méthode préférée :

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
    // Your UI update code goes here!
});

L'avantage de cette méthode est qu'elle permet d'obtenir l'essentiel de l'information. CoreApplicationView et est donc toujours disponible. Plus de détails aquí .

Il y a deux alternatives que vous pouvez utiliser.

Première alternative

Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher

Cela permet d'obtenir la vue active de l'application, mais cela vous donnera nul si aucune vue n'a été activée. Plus de détails aquí .

Deuxième alternative

Window.Current.Dispatcher

Cette solution ne fonctionnera pas si elle est appelée à partir d'un autre thread, car elle renvoie nul au lieu de la Répartiteur d'interface utilisateur . Plus de détails aquí .

16voto

Brett Pennings Points 206

Pour tous ceux qui utilisent C++/CX

Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
    CoreDispatcherPriority::Normal,
    ref new Windows::UI::Core::DispatchedHandler([this]()
{
    // do stuff
}));

2voto

aaram Points 21
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
            CoreDispatcherPriority.Normal,
            () => { // your code should be here});

1voto

Dave Friedel Points 99

Bien qu'il s'agisse d'un vieux fil de discussion, je voulais attirer l'attention sur un problème que les développeurs peuvent rencontrer et qui m'a affecté et a rendu extrêmement difficile le débogage dans les grandes applications UWP. Dans mon cas, j'ai refait le code suivant à partir des suggestions ci-dessus en 2014, mais j'étais parfois confronté à des blocages occasionnels de l'application qui étaient de nature aléatoire.

public static class DispatcherHelper
{
    public static Task RunOnUIThreadAsync(Action action)
    {
        return RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, action);
    }

    public static async Task RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority priority, Action action)
    {
        try
        {
            await returnDispatcher().RunAsync(priority, () =>
            {
                action();
            });
        }
        catch (Exception ex)
        {
            var noawait = ExceptionHandler.HandleException(ex, false);
        }
    }

    private static Windows.UI.Core.CoreDispatcher returnDispatcher()
    {
        return (Windows.UI.Xaml.Window.Current == null) ?
            CoreApplication.MainView.CoreWindow.Dispatcher :
            CoreApplication.GetCurrentView().CoreWindow.Dispatcher;
    }
}

Dans ce qui précède, j'ai utilisé une classe statique pour permettre l'appel du Dispatcher à travers l'application - ce qui permet un appel unique. Dans 95 % des cas, tout allait bien, même en cas de régression de l'assurance qualité, mais les clients signalaient un problème de temps à autre. La solution a été d'inclure l'appel ci-dessous, sans utiliser d'appel statique dans les pages actuelles.

            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            { 

            });

Ce n'est pas le cas lorsque je dois m'assurer que l'UI Thread a été appelé depuis App.xaml.cs ou mon Singleton NavigationService qui a géré le push/popping sur la pile. Le dispatcher perdait apparemment la trace de l'UI Thread appelé, puisque chaque page a son propre UI Thread, lorsque la pile avait une variété de messages déclenchés par le MessageBus.

J'espère que cela aidera d'autres personnes qui pourraient être affectées et c'est aussi là que je pense que chaque plateforme rendrait service à ses développeurs en publiant un projet complet couvrant les meilleures pratiques.

0voto

J. H. Points 39

En fait, je proposerais quelque chose dans ce sens :

return (Window.Current == null) ? 
    CoreApplication.MainView.CoreWindow.Dispatcher : 
    CoreApplication.GetCurrentView().CoreWindow.Dispatcher

Ainsi, si vous avez ouvert une autre vue/fenêtre, vous ne risquez pas de confondre les répartiteurs...

Ce petit bijou vérifie s'il y a bien une fenêtre. S'il n'y en a pas, il utilise le Dispatcher de MainView. S'il y a une vue, on utilise le Dispatcher de celle-ci.

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