without run method explained español ejemplos create await async c# wpf .net-4.5 async-await

run - create async method c#



¿Cuál es la diferencia entre InvokeAsync y BeginInvoke para WPF Dispatcher? (3)

[Editar - ambos son lo mismo]

Ahí

BeginInvoke funciona en el subproceso en el que se creó el asignador y InvokeAsync funciona con el subproceso al que está asociado el despachador.

Significa que si necesita procesar algo basado en el hilo actual del despachador, usará InvokeAsync o usar BeginInvoke.

EDITAR: - pero el comentario anterior no tiene sentido ya que no puede cambiar el hilo asociado del despachador una vez que se haya creado.

Estoy de acuerdo con la respuesta mencionada arriba ... gracias

Noté en .NET 4.5 que el Despachador de WPF había obtenido un nuevo conjunto de métodos para ejecutar cosas en el hilo del Dispatcher llamado InvokeAsync . Antes, .NET 4.5 teníamos Invoke y BeginInvoke que manejaban esto de forma sincrónica y asíncrona, respectivamente.

Además de la nomenclatura y las sobrecargas ligeramente diferentes disponibles, ¿hay diferencias importantes entre los BeginInvoke y InvokeAsync ?

Ah, y ya lo he comprobado, ambos pueden estar await :

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


Hay una diferencia en la firma del método:

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

Para el compilador BeginInvoke() crea el Object[] matriz Object[] implícitamente, mientras que para InvokeAsync() dicha matriz no es necesaria:

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)


No hay diferencias ya que el método BeginInvoke llama a un método privado LegacyBeginInvokeImpl que itslef llama al método privado InvokeAsyncImpl (el método utilizado por InvokeAsync ). Entonces es básicamente lo mismo. Parece que es una refactorización simple, sin embargo, es extraño que los métodos de BeginInvoke no se hayan marcado como obsoletos.

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; }