run programming parallel net library examples example await async asp c# .net asynchronous task-parallel-library

programming - task.run c#



Task.Factory.StartNew vs Task.Factory.FromAsync (2)

(1) causará (probablemente) que el grupo de subprocesos de .NET procese su Task .

(2) utilizará cualquier mecanismo que su par BeginIOMethod / EndIOMethod use nativamente para manejar la parte asincrónica, que puede o no involucrar al grupo de subprocesos de .NET.

Por ejemplo, si su BeginIOMethod está enviando un mensaje TCP a través de Internet, y en un momento posterior el destinatario le enviará un mensaje TCP en respuesta (recibido por EndIOMethod ), entonces la naturaleza asincrónica de la operación no será proporcionada por el grupo de subprocesos de .NET. La biblioteca TCP que se está utilizando proporciona la parte asíncrona.

Esto se puede lograr utilizando la clase TaskCompletionSource . Task.Factory.FromAsync puede crear un TaskCompletionSource<T> , devolver su Task<T> , luego usar EndIOMethod como desencadenante para colocar el Result en la Task<T> que se devolvió desde Task.Factory.FromAsync en el momento de la llamada. .

¿Cuál es la diferencia de rendimiento en términos de utilización de recursos?

La diferencia entre (1) y (2) es principalmente si el grupo de subprocesos de .NET tendrá o no se agregará su carga de trabajo. En general, lo correcto es elegir Task.Factory.FromAsync si solo tiene un par Begin... / End... y Task.Factory.StartNew contrario.

Si está utilizando C # 5.0, entonces debe usar la await task; sin bloqueo await task; en lugar de task.Wait(); . (Ver la respuesta de svick)

Supongamos que tenemos un método de E / S obligado (como un método para hacer llamadas a bases de datos). Este método se puede ejecutar tanto de forma síncrona como asíncrona. Es decir,

  1. Sincronización:

    IOMethod()

  2. Asincrónico:

    BeginIOMethod() EndIOMethod()

Luego, cuando ejecutamos el método de diferentes maneras, como se muestra a continuación, ¿cuál es la diferencia de rendimiento en términos de la utilización de los recursos?

  1. var task = Task.Factory.StartNew(() => { IOMethod(); }); task.Wait();

  2. var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... ); task.Wait();


var task = Task.Factory.StartNew(() => { IOMethod(); }); task.Wait();

Esto bloqueará un hilo del grupo de subprocesos mientras IOMethod() está ejecutando y también bloqueará el hilo actual debido al Wait() . Total de hilos bloqueados: 2.

var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... ); task.Wait();

Esto (muy probablemente) realizará la operación de forma asíncrona sin utilizar un hilo, pero bloqueará el hilo actual debido a Wait() . Total de hilos bloqueados: 1.

IOMethod();

Esto bloqueará el hilo actual mientras IOMethod() está ejecutando. Total de hilos bloqueados: 1.

Si necesita bloquear el hilo actual, o si bloquearlo está bien para usted, entonces debe usar esto, porque tratar de usar TPL en realidad no le dará nada.

var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... ); await task;

Esto realizará la operación de forma asíncrona sin usar un hilo, y también esperará a que la operación se complete de forma asíncrona, gracias a await . Total de hilos bloqueados: 0.

Esto es lo que debe usar si desea aprovechar la asincronía y puede usar C # 5.0.

var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... ); task.ContinueWith(() => /* rest of the method here */);

Esto realizará la operación de forma asíncrona sin usar un hilo, y también esperará a que la operación se complete de forma asincrónica, gracias a ContinueWith() . Total de hilos bloqueados: 0.

Esto es lo que debe usar si desea aprovechar la asincronía y no puede usar C # 5.0.