c# .net multithreading delegates

c# - Diferencia entre BeginInvoke y Thread.Start



.net multithreading (6)

BeginInvokes ejecuta el delegado de forma asincrónica en el subproceso de la interfaz de usuario (por lo que bloquea la interfaz de usuario), mediante la publicación de un mensaje en la ventana. Eso es lo que debe hacer si el código en el delegado accede a la interfaz de usuario.

El enfoque con Thread.Start ejecuta a los delegados en un nuevo hilo independiente.

Tengo una aplicación basada en cuadros de diálogo en la que delegaré la operación de E / S de lectura y escritura en un subproceso diferente.

Solo quiero aclarar si hay alguna diferencia entre dos enfoques ...

Primer enfoque: (Estoy haciendo esto en, mi formulario principal -Form.cs)

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

Segundo enfoque:

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

Me di cuenta de que BeginInvoke bloquea la interfaz de usuario por un segundo, mientras que el segundo enfoque no lo hace ...

Por favor ayuda


Como otros han publicado, Thread.Start lanzará un nuevo subproceso, y Control.BeginInvoke () ejecutará el código en el subproceso de la interfaz de usuario (es necesario si desea cambiar el valor de un campo, por ejemplo).

Sin embargo, he encontrado que la técnica más sencilla para ejecutar una tarea en segundo plano en WinForms es usar un BackgroundWorker . Lo sueltas en un formulario, conectas los eventos y llamas a RunWorkerAsync (). Luego escribe su tarea de fondo en el evento DoWork. Cualquier actualización de la interfaz de usuario se puede colocar en el evento RunWorkerCompleted.

El uso de un BackgroundWorker evita todo el manejo de subprocesos molestos e IsInvokeRequired stuff.

Aquí hay un artículo de instrucciones más detallado.


Prueba 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. */ }); } }

Con respecto a BeginInvoke (), se utiliza para que la función regrese inmediatamente y la siguiente línea se ejecute, y así sucesivamente, sin esperar a que el método termine.

La diferencia es que si creas un hilo, tendrás 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 administrado 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 finaliza la operación.

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. Yo usaría hilos más para objetos tipo servicio. (Piense en un objeto que permanece y escucha las conexiones TCP) y los métodos asíncronos para el trabajo en segundo plano detrás de una interfaz de usuario (vea también BackgroundWorker). No se preocupe si el primer enfoque tomó un segundo extra para comenzar: Thread.Abort () tampoco es siempre su mejor solución. Pruebe _abortar banderas en su código de proceso y bloquearlo.

Espero haber respondido a la pregunta.

Leo Bruzzaniti


la diferencia sería que el método BeginInvoke simplemente llama al delegado de forma asíncrona en el mismo hilo.

Usando Thread.Start, estarás creando un hilo completamente diferente.

Thread.Start definitivamente te dará un mejor rendimiento!


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

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

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


Thread.Start ejecuta en tu nuevo Thread .

Control.BeginInvoke ejecuta el método en el subproceso al que pertenece el Control al que pertenece. Si actualmente se encuentra en el subproceso del control, el método no se ejecuta hasta que devuelva el control al bucle de mensajes, por ejemplo, salga de su controlador de eventos.