¿Cuál es la diferencia entre Invoke () y BeginInvoke ()

BeginInvoke() pregunto cuál es la diferencia entre BeginInvoke() y Invoke() ?

Principalmente para lo que se usaría cada uno.

EDITAR: ¿Cuál es la diferencia entre crear un objeto de subprocesamiento y invocar invocación sobre eso y simplemente llamar a BeginInvoke() en un delegado? ¿O son la misma cosa?

¿Quiere decir Delegate.Invoke / BeginInvoke o Control.Invoke / BeginInvoke?

  • Delegate.Invoke: se ejecuta de forma síncrona en el mismo hilo.
  • Delegate.BeginInvoke: se ejecuta de forma asincrónica en un hilo de subprocesos.
  • Control.Invocar: se ejecuta en el subproceso de interfaz de usuario, pero el subproceso de llamada espera su finalización antes de continuar.
  • Control.BeginInvoke: se ejecuta en el subproceso de interfaz de usuario, y el subproceso de llamada no espera a completarse.

La respuesta de Tim menciona cuándo es posible que desee utilizar BeginInvoke, aunque estaba orientado principalmente a Delegate.BeginInvoke, sospecho.

Para las aplicaciones de Windows Forms, sugeriría que usara BeginInvoke. De esta forma, no tiene que preocuparse por el punto muerto, por ejemplo, pero debe entender que es posible que la interfaz de usuario no se haya actualizado en el momento en que vuelva a examinarlo. En particular, no debe modificar los datos que la secuencia de la interfaz de usuario podría utilizar para fines de visualización. Por ejemplo, si tiene una persona con propiedades FirstName y LastName, y lo hizo:

 person.FirstName = "Kevin"; // person is a shared reference person.LastName = "Spacey"; control.BeginInvoke(UpdateName); person.FirstName = "Keyser"; person.LastName = "Soze"; 

entonces la IU bien puede terminar mostrando “Keyser Spacey”. (Existe la posibilidad de que muestre “Kevin Soze” pero solo a través de la rareza del modelo de memoria).

Sin embargo, a menos que tenga este tipo de problema, Control.BeginInvoke es más fácil de acertar, y evitará que su hilo de fondo tenga que esperar sin una buena razón. Tenga en cuenta que el equipo de Windows Forms ha garantizado que puede usar Control.BeginInvoke de una manera “disparar y olvidar”, es decir, sin llamar a EndInvoke. Esto no ocurre con las llamadas asincrónicas en general: normalmente, cada BeginXXX debe tener una llamada EndXXX correspondiente, generalmente en la callback.

Sobre la base de la respuesta de Jon Skeet, hay momentos en los que desea invocar a un delegado y esperar a que se complete su ejecución antes de que el hilo actual continúe. En esos casos, la llamada Invoke es lo que desea.

En aplicaciones de subprocesos múltiples, es posible que no desee que un subproceso espere en un delegado para finalizar la ejecución, especialmente si ese delegado realiza E / S (lo que podría hacer que el delegado y su bloque de subprocesos).

En esos casos, el BeginInvoke sería útil. Al invocarlo, le está diciendo al delegado que comience, pero luego su hilo es libre de hacer otras cosas en paralelo con el delegado.

El uso de BeginInvoke aumenta la complejidad de su código, pero hay momentos en que el rendimiento mejorado vale la pena la complejidad.

La diferencia entre Control.Invoke() y Control.BeginInvoke() es,

  • BeginInvoke() progtwigrá la acción asíncrona en el hilo de la GUI. Cuando se progtwig la acción asincrónica, su código continúa. Algún tiempo después (no se sabe exactamente cuándo) se ejecutará su acción asincrónica
  • Invoke() ejecutará su acción asíncrona (en el hilo de la GUI) y esperará hasta que su acción se haya completado.

Una conclusión lógica es que un delegado que pase a Invoke() puede tener parámetros de salida o un valor de retorno, mientras que un delegado que pase a BeginInvoke() no pueda (debe usar EndInvoke para recuperar los resultados).

Solo para dar un breve ejemplo de trabajo para ver el efecto de su diferencia

 new Thread(foo).Start(); private void foo() { this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { myTextBox.Text = "bing"; Thread.Sleep(TimeSpan.FromSeconds(3)); }); MessageBox.Show("done"); } 

Si usa BeginInvoke , MessageBox aparece simultáneamente a la actualización de texto. Si usa Invocar , MessageBox aparece después de 3 segundos de inactividad. Por lo tanto, muestra el efecto de una llamada asincrónica ( BeginInvoke ) y una llamada síncrona ( Invoke ).

Delegate.BeginInvoke () colas asincrónicamente la llamada de un delegado y devuelve el control de inmediato. Al usar Delegate.BeginInvoke (), debe llamar a Delegate.EndInvoke () en el método de callback para obtener los resultados.

Delegate.Invoke () llama sincrónicamente al delegado en el mismo hilo.

Artículo de MSDN

Simplemente agregando por qué y cuándo usar Invoke ().

Invoke () y BeginInvoke () clasifican el código que especifiques en la cadena de distribución.

Pero a diferencia de BeginInvoke (), Invoke () detiene su hilo hasta que el despachador ejecute su código. Es posible que desee utilizar Invoke () si necesita pausar una operación asincrónica hasta que el usuario haya proporcionado algún tipo de comentario.

Por ejemplo, puede llamar a Invoke () para ejecutar un fragmento de código que muestre un cuadro de diálogo Aceptar / Cancelar. Después de que el usuario haga clic en un botón y se complete el código de referencia, volverá el método invoke () y podrá actuar en función de la respuesta del usuario.

Ver Pro WPF en C # capítulo 31