2016-05-17 3 views
3

Я работаю с async-await и задачами, но я не могу понять одну вещь:Асинхронный ждут и нити

ли асинхронная задача выполняется в отдельном потоке?

Как говорит MSDN (Asynchronous programming):

Асинхронные и поджидают ключевые слова не вызывают дополнительные потоки, которые будут созданы. Асинхронные методы не требуют многопоточности, потому что метод async не запускается в своем потоке.

Но в слове в описании ThreadPool класса (ThreadPool Class):

Примеры операций, которые используют пул потоков темы включают в себя следующее:

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

Итак, теперь я не понимаю, если задание async использует отдельную тему. Объясни мне пожалуйста. Благодарю.

+0

Существует два вида задач: делегирование задач (выполнение кода) и обещание задач (которые представляют собой будущие события). Только делегированные задачи фактически * запускаются *, и они могут или не могут выполняться в пуле потоков. Подробнее [в моем блоге] (http://blog.stephencleary.com/2014/04/a-tour-of-task-part-0-overview.html). –

ответ

4

A Task не обязательно представляют собой дополнительную тему.

Если вы await a Task, вы возвращаете поток управления вызывающему устройству до тех пор, пока «кто-то» не установит Task как выполненный.

Если вы начинаете Task через Task.Run() или Task.Factory.StartNew(), то действие переходит к этим вызовам выполняются в другом потоке (не новый, но один из ThreadPool).

+0

На самом деле, он никогда не создает новый поток для выполнения задачи, в которой он всегда использует один, взятый из ThreadPool, и в случаях избыточной подписки. CLR избегает избыточной подписки в пуле потоков в задачах очередей и дросселирования их запуск. – Karolis

+0

@ Карл спасибо за исправление, обновил свой ответ. –

2

async/ждут работу над Tasks (ну не совсем, он работает на «awaitables», но просто говорит, что «Задача» достаточно близко для обсуждения).

Задачи представляют собой «Единицу работы, которая будет завершена позднее». Эта единица работы может быть новой нитью из пула потоков, запущенной через Task.Run(, это может быть вызов системы IO, например DbDataReader.ReadAsync(), или это может быть вызвано событием от TaskCompletionSource.

Я рекомендую прочитать Стивен Клири async and await intro, чтобы узнать больше о

3

Чтобы поместить его в простой термин Task может работать на другом Thread, а также он может работать на вызывающей Thread. Задача возьмет Thread от ThreadPoolТОЛЬКО, когда вызывающий абонент Thread не имеет ресурсов для запуска другого Task. Task будет запущен на вызывающем абоненте Thread, когда у него достаточно ресурсов для запуска другого Task (режим ожидания).

По сравнению с нитью, задача является более высокого уровня абстракции он представляет собой параллельную операцию, которая может или не может быть подкрепленная нитью. Задачи являются составными (их можно объединить через использование продолжений). Они могут использовать пул потоков, чтобы уменьшить задержку запуска, и с помощью объекта TaskCompletionSource, они могут использовать подход обратного вызова, который во время ожидания операций с привязкой к вводу/выходу полностью игнорирует потоки .

Источник: страница 565 «C# 5.0 в двух словах» Джозефа Альбахари, Бен Альбахари.

+0

Это объяснение неверно. «Нагрузка на резьбу», что бы это ни было, не определяет, будет ли выполняться новая задача в текущем или другом потоке. – GSerg

+0

@Gserg Не могли бы вы предоставить источник, который не одобряет это? – Karolis

+0

Ответы на эти вопросы, на вопросы, связанные с этим вопросом (http://stackoverflow.com/q/13429294/11683, http://stackoverflow.com/q/17661428/11683) и ресурсы, связанные с оттуда. – GSerg

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