Diferencia entre delegado.BeginInvoke y usando hilos ThreadPool en C#
En C# hay alguna diferencia entre usar un delegado para hacer algún trabajo de forma asíncrona (llamando a BeginInvoke()) y usar un subproceso 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 asincrónico, ¿hay alguna diferencia?
1 answers
Joe Duffy, en su Concurrent Programming on Windows
libro (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 ordinario síncronoInvoke
. Si bien esta es una buena característica del modelo de programación, debe mantenerse alejado de ellos siempre que sea posible. La implementación utiliza una infraestructura remota que impone una sobrecarga considerable a la invocación asincrónica. Cola de trabajo al grupo de subprocesos directamente es a menudo un mejor enfoque, aunque eso significa que tienes que coordinar la lógica del encuentro tú mismo.
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 alrededor de 20 segundos. Sustitución de la llamada BeginInvoke
por
System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
Interlocked.Increment(ref counter);
});
Cambia el tiempo de ejecución a 864ms.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-26 22:34:03