2009-08-04 14 views
20

Tengo una aplicación basada en un diálogo en la que voy a delegar la lectura de lectura de la operación de E/S a un hilo diferente.Diferencia entre BeginInvoke y Thread.Start

sólo quiero aclarar es que hay alguna diferencia entre dos enfoques ..

Primera aproximación: (Estoy haciendo esto, mi principal forma -Form.cs)

delegate void Action(); 
Action _action = new Action(Method); 
this.BeginInvoke(_action); 

Segundo enfoque:

Thread th = new Thread(new ThreadStart(_action)); 
th.Start(); 

noté que BeginInvoke cuelga la interfaz de usuario para un segundo, mientras que el segundo enfoque no lo hacen ..

Por favor ayuda

+4

Para obtener información, es útil dejar en claro si se refiere a Control.BeginInvoke y Delegate.BeginInvoke; Creo que te refieres al primero, pero son casi exactamente opuestos, por lo que la diferencia es importante. –

+0

es el primer enfoque (Control.BeginInvoke), ya que estoy haciendo esto en un Formulario. –

Respuesta

17

BeginInvoke publicará la acción en la cola de mensajes de la bomba de mensajes en el mismo hilo que el Form, no creará un nuevo hilo.

Control.BeginInvoke se comporta de forma similar a un inicio de subproceso asíncrono, pero tiene importantes diferencias internas.

Lea con más detalle un artículo here.

0

la diferencia sería que el método BeginInvoke simplemente llama al delegado asincrónicamente en el MISMO hilo.

Al utilizar Thread.Start, creará un hilo completamente diferente.

Thread.Start definitivamente le dará un mejor rendimiento!

+1

Un mejor rendimiento es una suposición ... y con un hilo que debe ejecutar en las antiguas CrossThreadedExceptions ... – Pondidum

+0

es una suposición basada en una prueba básica. ver una prueba rápida aquí: http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.html pero sí ... hay otros factores a tener en cuenta, pero CrossThreadedExceptions no es exactamente un problema si 'estar al tanto de ellos ... – Sk93

8

BeginInvokes ejecuta el delegado de forma asincrónica en el subproceso de la interfaz de usuario (por lo que cuelga la interfaz de usuario), al publicar un mensaje en la ventana. Eso es lo que debe hacer si el código del delegado accede a la IU.

El enfoque con Thread.Start ejecuta los delegados en una nueva cadena independiente.

3

Thread.Start lo ejecuta en su nuevo Thread.

Control.BeginInvoke ejecuta el método en la secuencia a la que pertenece el control. Si actualmente se encuentra en el hilo del control, el método no se ejecutará hasta que devuelva el control al bucle de mensajes, p. salga de su controlador de eventos.

3

Pruebe esto.

class Form1: Form 
{ 
    public void ButtonWasClicked(object sender, EventArgs e) 
    { 
     /* Call the UI's Invoke() method */ 
     this.Invoke((MethodInvoker)delegate() 
     { 
      /* Stuff to do.. you can access UI elements too without 
      * the nasty "Control accessed from another thread.." 
      * Use BeginInvoke() only if you have code after this section 
      * that you want the UI to execute without waiting for this 
      * inner blockto finish. 
      */ 
     }); 
    } 
} 

En cuanto BeginInvoke(), se utiliza por lo que la función devolverá inmediatamente y la línea siguiente será ejecutada y así sucesivamente y así sucesivamente sin esperar a que el método para terminar.

La diferencia es que si crea un hilo, tendrá más control sobre él como cualquier otro hilo. ¡Te encontrarás con CrossThreadExceptions! Mientras que si usa IAsyncResult y BeginInvoke(), no tendrá control sobre el flujo de ejecución de la operación asíncrona ya que es administrada por el tiempo de ejecución.

Con la invocación también puede enviar más parámetros a un método y llamar a un método una vez que la operación haya finalizado.

MyDelegateWithTwoParam del = new MyDelegateWithTwoParam(_method); 
AsyncCallback callback = new AsyncCallback(_callbackMethod); 
IAsyncResult res = del.BeginInvoke(param1, param2, callback, null); 

private void _callbackMethod(IAsyncResult iar) { 
    /* In this method you can collect data that your operation might have returned. 
    * If MyDelegateWithTwoParam has a return type, you can find out here what i was. */ 
} 

He utilizado ampliamente tanto para el desarrollo de la interfaz de usuario. Usaría hilos más para objetos similares a servicios. (Piense en un objeto que permanezca y escuche las conexiones TCP) y métodos asincrónicos para el trabajo de fondo detrás de una IU (eche un vistazo a BackgroundWorker también). No se preocupe si el primer enfoque tomó un segundo extra para comenzar: Thread.Abort() no es , siempre es la mejor solución tampoco. Pruebe _abort banderas en su código de proceso y bloquearlo.

Espero que haya respondido la pregunta.

Leo Bruzzaniti

+1

Solución pequeña: en el primer fragmento de código, agregue: ");" sin comillas para cerrar el método Invoke y finalizar la declaración. – Magnus

1

Como otros han publicado, hilo.start pondrá en marcha un nuevo hilo, y Control.BeginInvoke() se ejecutará código en el hilo de interfaz de usuario (necesario si desea cambiar el valor de un campo, por ejemplo,)

Sin embargo, he encontrado que la técnica más simple para ejecutar una tarea en segundo plano en WinForms es usar un BackgroundWorker. Lo coloca en un formulario, conecta los eventos y llama a RunWorkerAsync(). Luego, escribe tu tarea de fondo en el evento DoWork. Cualquier actualización de UI se puede colocar en el evento RunWorkerCompleted.

El uso de un BackgroundWorker evita todo el molesto manejo de subprocesos y todo lo relacionado con IsInvokeRequired.

Aquí hay una más detallada how-to article.

Cuestiones relacionadas