Является ли Task.Delay действительно асинхронным, как операция ввода-вывода, т.е. полагается ли он на оборудование и прерывания, а не на поток?

Dec 09 2020

Я нашел тонну связанного контента, который ходил вокруг да около, и мне так и не удалось найти ответ. Я почти на 100% уверен, что Task.Delay(int)он не использует поток, потому что я могу запустить этот код на своей машине только с 16 логическими процессорами:

var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);

И это займет десять секунд. Я бы подумал, что если бы он использовал примерно сто тысяч потоков, это заняло бы немного больше времени.

Итак, мой вопрос: как это Task.Delay(int)работает? Не так, как указывает этот плохо озаглавленный вопрос SO , а с точки зрения потоковой передачи и аппаратных ресурсов.

Ответы

4 StephenCleary Dec 11 2020 at 12:24

В текущей реализации .NET существует единственный «поток таймера», который просто отслеживает экземпляры управляемого таймера и вызывает их события в нужное время. Этот поток таймера блокирует свой управляющий сигнал с таймаутом, установленным на время следующего таймера. Управляющий сигнал используется для добавления / удаления / изменения таймеров, поэтому по истечении времени ожидания этого запроса на блокировку поток таймера знает, что сработал следующий таймер. Это обычная операция блокировки потока, поэтому внутренне поток простаивает и удаляется из очереди планировщика до тех пор, пока эта операция блокировки не завершится или не истечет время ожидания. Тайм-аут этих операций обрабатывается прерыванием таймера планировщика ОС.

Таким образом, технически существует поток, но это только один поток на процесс, а не один поток на каждый Task.Delay.

Я еще раз подчеркиваю, что это есть в текущей реализации .NET. Были предложены другие решения, такие как один поток таймера на ЦП или динамический пул потоков таймера. Возможно, с ними экспериментировали и по какой-то причине отвергли, или, возможно, в будущем будет принято альтернативное решение. AFAIK это нигде официально не задокументировано, так что это деталь реализации.