2016-06-22 2 views

ответ

6

Как я описываю в своем блоге long-running I/O operations do not require a thread at all. Скорее, они используют естественно-асинхронный ввод-вывод, который не требует потока.

Драйверы устройств обычно используют DMA, что позволяет устройству напрямую считывать/записывать из основной ОЗУ системы. .NET дополняет этот подход с помощью IOCP (порт завершения ввода-вывода), который является частью пула потоков, позволяя одному потоку (или очень немногим потокам) на однодоменное ожидание на огромном количестве операций ввода-вывода.

Для ответа на вторую половину вашего вопроса, асинхронный метод будет резюме с контекстом запроса, но может или не может быть на том же потоке, он был на перед await. Более распространенный сценарий - когда операция ввода-вывода завершается, он сигнализирует IOCP, который принимает поток пула потоков, чтобы выполнить немного домашнего хозяйства (маркировка задачи как завершена и т. Д.), А затем тот же поток входит в ASP.NET запрашивать контекст и возобновлять выполнение обработчика. Это не всегда Бывают - иногда нужен переключатель потоков, но это самый распространенный случай.

+0

Спасибо, Стивен Клири! – Sunny

+0

Что делать, если это не операция ввода-вывода. Если это бизнес-логика, которая выполняется внутри функции и потребляет столько времени. Разве это не создало бы новый поток. – Sunny

+0

@Sunny: Нет. Если вы используете 'async' без' await', тогда код запускается непосредственно в вызывающем потоке. Если вы используете 'await Task.Run', то' Task.Run' (* not * the 'async' /' await') использует отдельный поток пула потоков (обратите внимание: это не рекомендуется на ASP.NET). –

1

Чтобы ответить на ваш вопрос, все темы взяты из пула потоков.

Пример сценария может быть задан таким образом, когда запрос получен сервером, доступный поток извлекается из пула для обслуживания запроса.

Затем вы создаете новую нить (либо Async, либо другие средства). Теперь из пула извлекается новый поток, чтобы выполнить запрос вашего тела Async.

Между тем исходная нить освобождается в пул и возвращается к обработке другого запроса.

Когда ваша потоковая обработка закончена, она возвращает другой поток (может не совпадать с исходным потоком) из пула и завершает ваш запрос.

Это полная трата времени, если этот процесс связан с ЦП, поскольку вы блокируете один поток (который из одного пула). Однако операции с привязкой IO можно обрабатывать так, так как они не используют нити.

Смежные вопросы