¿Es Task.Delay verdaderamente asincrónico como lo es una operación de E / S, es decir, se basa en el hardware y las interrupciones en lugar de un hilo?
He encontrado un montón de contenido relacionado que anda por las ramas y nunca he podido encontrar una respuesta. Estoy casi 100% seguro de que Task.Delay(int)
no usa un hilo, porque puedo ejecutar este código en mi máquina con solo 16 procesadores lógicos:
var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);
Y tarda diez segundos en completarse. Si estuviera usando aproximadamente cien mil hilos, creo que tomaría un poco más de tiempo.
Entonces mi pregunta es ¿cómo Task.Delay(int)
funciona? No de la manera que indica esta pregunta de SO mal titulada , sino desde el punto de vista de los subprocesos y los recursos de hardware.
Respuestas
En la implementación actual de .NET, hay un único "subproceso de temporizador" que solo realiza un seguimiento de las instancias de temporizador administradas y genera sus eventos en los momentos adecuados. Este hilo del temporizador bloqueará su señal de control con un tiempo de espera establecido en el tiempo de vencimiento del siguiente temporizador. La señal de control se usa para agregar / eliminar / cambiar temporizadores, por lo que cuando se agota el tiempo de espera de esta solicitud de bloqueo, el hilo del temporizador sabe que se ha disparado el siguiente temporizador. Esta es una operación de bloqueo de subprocesos normal, por lo que internamente, el subproceso está inactivo y se elimina de la cola del planificador hasta que la operación de bloqueo se completa o se agota el tiempo de espera. El tiempo de espera de esas operaciones es manejado por la interrupción del temporizador del programador del SO.
Entonces, técnicamente, hay un hilo, pero es solo un hilo por proceso, no un hilo por Task.Delay
.
De nuevo enfatizo que esto está en la implementación actual de .NET. Se han propuesto otras soluciones, como un subproceso de temporizador por CPU o un grupo dinámico de subprocesos de temporizador. Quizás fueron experimentados y rechazados por alguna razón, o quizás se adopte una solución alternativa en el futuro. AFAIK, esto no está documentado oficialmente en ninguna parte, por lo que este es un detalle de implementación.