waitcallback thread example ejemplo c# multithreading threadpool

example - Diferencia entre delegate.BeginInvoke y el uso de hilos de ThreadPool en C#



threadpool.queueuserworkitem example c# (1)

En C # hay alguna diferencia entre usar un delegado para hacer un trabajo asincrónico (llamar a BeginInvoke ()) y usar un hilo ThreadPool como se muestra a continuación

public void asynchronousWork(object num) { //asynchronous work to be done Console.WriteLine(num); } public void test() { Action<object> myCustomDelegate = this.asynchronousWork; int x = 7; //Using Delegate myCustomDelegate.BeginInvoke(7, null, null); //Using Threadpool ThreadPool.QueueUserWorkItem(new WaitCallback(asynchronousWork), 7); Thread.Sleep(2000); }

Editar:
BeginInvoke se asegura de que se use un subproceso del grupo de subprocesos para ejecutar el código asíncrono, así que ¿hay alguna diferencia?


Joe Duffy, en su libro Concurrent Programming on Windows (página 418), dice esto acerca de Delegate.BeginInvoke :

Todos los tipos de delegados, por convención, ofrecen un método BeginInvoke y EndInvoke junto con el método de Invoke sincrónico ordinario. Si bien esta es una buena función de modelo de programación, debes mantenerte alejado de ellos siempre que sea posible. La implementación utiliza una infraestructura remota que impone una sobrecarga considerable a la invocación asíncrona. El trabajo en cola para el grupo de subprocesos directamente es a menudo un mejor enfoque, aunque eso significa que usted mismo debe coordinar la lógica de encuentro.

EDITAR: he creado la siguiente prueba simple de los gastos generales relativos:

int counter = 0; int iterations = 1000000; Action d = () => { Interlocked.Increment(ref counter); }; var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); for (int i = 0; i < iterations; i++) { var asyncResult = d.BeginInvoke(null, null); } do { } while(counter < iterations); stopwatch.Stop(); Console.WriteLine("Took {0}ms", stopwatch.ElapsedMilliseconds); Console.ReadLine();

En mi máquina, la prueba anterior se ejecuta en unos 20 segundos. Sustitución de la llamada BeginInvoke con

System.Threading.ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref counter); });

Cambia el tiempo de ejecución a 864ms.