82 votes

Quelle est la différence entre InvokeAsync et BeginInvoke pour WPF Dispatcher

J'ai remarqué dans .NET 4.5 que le Répartiteur WPF avait obtenu un nouvel ensemble de méthodes d'exécuter des trucs sur le Répartiteur du thread appelé InvokeAsync. Avant, .NET 4.5 nous avons dû Appeler et BeginInvoke qui a géré cette syncronously et de manière asynchrone, respectivement.

En plus de la désignation et de la légèrement différentes surcharges disponibles, existe-il des différences majeures entre l' BeginInvoke et de la InvokeAsync méthodes?

Oh, et j'ai déjà vérifié, les deux peuvent être awaited:

private async Task RunStuffOnUiThread(Action action)
{
    // both of these works fine
    await dispatcher.BeginInvoke(action);
    await dispatcher.InvokeAsync(action);
}

54voto

Sisyphe Points 3391

Il n'y a pas de différences que l' BeginInvoke des appels de méthode privée LegacyBeginInvokeImpl méthode qui itslef appelle la méthode InvokeAsyncImpl (la méthode utilisée par InvokeAsync). Donc, c'est essentiellement la même chose. Il semble que c'est un simple, mais c'est étrange l' BeginInvoke méthodes n'étaient pas marqué comme obsolète.

BeginInvoke :

    public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method)
    {
        return this.LegacyBeginInvokeImpl(priority, method, null, 0);
    }

    private DispatcherOperation LegacyBeginInvokeImpl(DispatcherPriority priority, Delegate method, object args, int numArgs)
    {
        Dispatcher.ValidatePriority(priority, "priority");
        if (method == null)
        {
            throw new ArgumentNullException("method");
        }
        DispatcherOperation dispatcherOperation = new DispatcherOperation(this, method, priority, args, numArgs);
        this.InvokeAsyncImpl(dispatcherOperation, CancellationToken.None);
        return dispatcherOperation;
    }

InvokeAsync :

    public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority)
    {
        return this.InvokeAsync(callback, priority, CancellationToken.None);
    }

    public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority, CancellationToken cancellationToken)
    {
        if (callback == null)
        {
            throw new ArgumentNullException("callback");
        }
        Dispatcher.ValidatePriority(priority, "priority");
        DispatcherOperation dispatcherOperation = new DispatcherOperation(this, priority, callback);
        this.InvokeAsyncImpl(dispatcherOperation, cancellationToken);
        return dispatcherOperation;
    }

17voto

user2341923 Points 443

Il existe une différence dans la signature de la méthode:

 BeginInvoke(Delegate, Object[])
InvokeAsync(Action)
 

Pour BeginInvoke() compilateur crée implicitement le tableau Object[] tandis que pour InvokeAsync() tel tableau n'est pas nécessaire:

 IL_0001:  ldarg.0
IL_0002:  call       instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher()
IL_0007:  ldarg.1
IL_0008:  ldc.i4.0
IL_0009:  newarr     [mscorlib]System.Object
IL_000e:  callvirt   instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::BeginInvoke(class [mscorlib]System.Delegate, object[])


IL_0014:  ldarg.0
IL_0015:  call       instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher()
IL_001a:  ldarg.1
IL_001b:  callvirt   instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::InvokeAsync(class [mscorlib]System.Action)
 

0voto

D J Points 2378

[Edit - les deux sont même]

Thereotically

BeginInvoke fonctionne sur le thread sur lequel répartiteur a été créé et InvokeAsync fonctionne avec thread sur lequel répartiteur est associé.

Cela signifie que si vous avez besoin de traiter quelque chose basé sur le thread en cours de répartiteur, vous allez utiliser la InvokeAsync d'autre de BeginInvoke.

EDIT: mais au-dessus de commentaire est vide de sens que vous ne pouvez pas changer les associés fil de dispatcher une fois qu'il est créé.

D'accord avec ci-dessus mention réponse.. merci

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