method - task.run c#
async-await threading internals (4)
Quiero decir, ¿no necesita generar algún tipo de trabajador para lanzar el evento? En el nivel muy bajo, debe haber algún bucle síncrono que bloquee un resultado de lectura de hilo de db.
Creará un puerto de finalización de IO (IOCP) que representa una tarea que se está procesando fuera y el hilo continuará con otras cosas. Luego, cuando el IOCP notifique que la tarea está lista, un hilo recogerá el estado del IOCP y continuará la tarea.
http://www.drdobbs.com/cpp/multithreaded-asynchronous-io-io-comple/201202921
Los puertos de terminación de E / S brindan una solución elegante al problema de escribir aplicaciones de servidor escalables que usan subprocesamiento y E / S asíncronas.
Tengo curiosidad acerca de la asincronización a la espera de threading interno.
Todos afirman que la sincronización es mucho mejor en el caso del rendimiento, porque libera los hilos que están esperando una respuesta a una llamada asincrónica larga. Ok, lo entiendo.
Pero consideremos este escenario.
Tengo un método asíncrono A que ejecuta una operación asíncrona en la base de datos. La API de la base de datos expone la función BeginQuery y el evento QueryCompleted. Envolví esos con una tarea (con el uso de TaskCompletionSource).
Mi pregunta es qué sucede debajo de llamar BeginQuery y activar el evento QueryCompleted.
Quiero decir, ¿no necesita generar algún tipo de trabajador para lanzar el evento? En el nivel muy bajo, debe haber algún bucle síncrono que bloquee un resultado de lectura de hilo de db.
Lo que supongo es que cualquier llamada asíncrona debe generar un hilo para manejar realmente la respuesta (tal vez esperarla en un bucle c ++ de bajo nivel en el código del controlador).
Entonces, nuestra única "ganancia" es que el hilo de la persona que llama puede liberarse cuando otro hilo está haciendo su trabajo.
¿Llamar a un método asíncrono siempre crea un nuevo hilo de trabajo?
¿Alguien podría confirmar mi comprensión?
Quiero decir, ¿no necesita generar algún tipo de trabajador para lanzar el evento? En el nivel muy bajo, debe haber algún bucle síncrono que bloquee un resultado de lectura de hilo de db.
Incluso cuando realmente tiene que esperar por un objeto kernel (como un evento de restablecimiento manual), puede convertir un código síncrono de bloqueo en uno asíncrono y liberar el hilo del bloqueo (actualizado: un escenario de la vida real ).
Por ejemplo, código síncrono:
void Consume()
{
var completedMre = new ManualResetEvent(false);
producer.StartOperation(completedMre);
completedMre.WaitOne(); // blocking wait
Console.WriteLine(producer.DequeueResult());
}
Analizador asincrónico:
async Task ConsumeAsync()
{
var completedMre = new ManualResetEvent(false);
producer.StartOperation(completedMre);
var tcs = new TaskCompletionSource<Result>();
ThreadPool.RegisterWaitForSingleObject(completedMre,
(s, t) => tcs.SetResult(producer.DequeueResult()),
null, Timeout.Infinite, true);
var result = await tcs.Task;
Console.WriteLine(result);
}
La versión asíncrona escala hasta 64 veces mejor ( MAXIMUM_WAIT_OBJECTS
, es la cantidad máxima de objetos kernel que se pueden agregar mediante RegisterWaitForSingleObject
para esperar en un único hilo). Por lo tanto, puede llamar a Consume()
durante 64 veces en paralelo y bloqueará 64 subprocesos. O puede llamar a ConsumeAsync
por 64 veces y bloqueará solo un hilo.
Todos afirman que la sincronización es mucho mejor en el caso del rendimiento, porque libera los hilos que están esperando una respuesta a una llamada asincrónica larga.
Si y no. El punto detrás de la async
es liberar el hilo que llama. En aplicaciones de interfaz de usuario, el principal beneficio de la función async
es la capacidad de respuesta, ya que el hilo de la interfaz de usuario se libera. En aplicaciones de servidor, el principal beneficio de async
es la escalabilidad, porque el hilo de solicitud se libera para manejar otras solicitudes.
Entonces, nuestra única "ganancia" es que el hilo de la persona que llama puede liberarse cuando otro hilo está haciendo su trabajo. ¿Llamar siempre a un método asíncrono está creando un nuevo hilo de trabajo?
No. En el nivel del sistema operativo, todas las E / S son asincrónicas. Son las API síncronas las que bloquean una secuencia mientras la E / S asíncrona subyacente está en progreso. Hace poco escribí esto en una publicación de blog: no hay ningún hilo .
Los métodos asíncronos no crean subprocesos nuevos, se basan en Task
s, que pueden o no usar subprocesos (como con TaskCompletionSource
), e incluso cuando lo hacen no hay sobrecarga porque usan ThreadPool
.