Async / Await против потоков


100

В .Net 4.5 Microsoft добавила новую Async/Awaitфункцию для упрощения асинхронного кодирования. Однако мне интересно

  1. Может Async/Awaitполностью заменить старый способ использования Threads?
  2. Является ли Async/Awaitспособен делать то , что Threadможет сделать асинхронно?
  3. Может использоваться Async/Awaitтолько с некоторыми методами, например, WebClient.DownloadStringAsyncили я могу преобразовать любой синхронный метод, чтобы использовать его, Async/Awaitа не блокировать основной поток?

2
Потоки и Async / Await не связаны между собой. Вы можете комбинировать их, но это не обязательно.
— dtb 01

2
Я думал, что Async / Await делает то же самое, что new Thread(() => {Some Work}).Start();делает ?! не так ли?
— Roman Ratskey 01

2
Нет. Ваше предположение неверно. Возможно, вы думаете о Task.Run (TPL), который часто сочетается с Async / Await, но также не связан с ним и не должен использоваться с ним.
— dtb 01

4
@dtb: Итак, когда использовать Async / Await, а когда - Threads? Меня действительно смущает разница между Task.Run, Thread.Start, Async / Await. Если бы вы могли дать мне хорошее объяснение, которое
— помогло

2
Async / await не создает и никаким другим образом не использует потоки.
— wRAR 01

Ответы:


79

может ли он полностью заменить старый способ использования потоков?

Нет. Нить может делать гораздо больше полезных вещей. Await специально разработан, чтобы иметь дело с чем-то, что требует времени, чаще всего с запросами ввода-вывода. Что традиционно делалось с обратным вызовом, когда запрос ввода-вывода был завершен. Написание кода, который полагается на эти обратные вызовы, довольно сложно, await значительно его упрощает.

способен делать то, что поток может делать асинхронно?

Примерно. Await просто заботится о задержке, иначе он не делает ничего, что делает поток. Выражение await справа от ключевого слова await - это то, что выполняет свою работу. В идеале он вообще не использует поток, он отправляет запрос драйвера, и как только драйвер завершает передачу данных, он генерирует обратный вызов уведомления о завершении. Работа в сети - это, безусловно, наиболее распространенное использование, задержки в сотни миллисекунд являются обычным явлением и являются неизбежным побочным эффектом при перемещении сервисов с настольных компьютеров или локальной сети в «облако». При синхронном использовании таких сервисов пользовательский интерфейс не будет отвечать на запросы.

может использоваться только с некоторыми методами, такими как WebClient.DownloadStringAsync

Нет. Вы можете использовать его с любым методом, возвращающим Task. Методы XxxxAsync () - это просто предварительно подготовленные методы в .NET framework для обычных операций, требующих времени. Как загрузка данных с веб-сервера.


4
В современном аспекте C #, какой лучший подход для достижения асинхронных обратных вызовов для внешних API?
— bonCodigo

5
Охваченный в последнем абзаце, используйте Task.
— Ханс Пассан

Я ожидал, что поток может сделать то, что нельзя сделать с помощью асинхронного программирования в качестве примера.
— Саид Нямати,

1
Не могли бы вы подробнее рассказать о том, что «ветка может делать еще много полезных вещей»? Было бы полезно понять, для каких функций потоки asyncне подходят.
— Benjohn

1
Стоит упомянуть await Task.Runо работе с процессором. Если я правильно понимаю, иногда получается то, что в противном случае можно было бы создать поток или фоновый рабочий.
— ToolmakerSteve

15

Официальное заявление по этому поводу. Хотя вы должны понимать разницу между потоками и асинхронным программированием, прежде чем слепо заменять одни вещи другими.


Это похоже на первый ресурс, который я прочитал о Threads и Async / Await, который ясен и краток.
— Арман Биматов 07

2
Этот ответ содержит только ссылку на документацию. Поскольку ссылка может устареть, ответ также может стать устаревшим - или, что еще хуже, - полностью бесполезным. Мы рекомендуем пользователям Stack вместо этого размещать соответствующие части ссылок непосредственно в своем вопросе.
— HimBromBeere

1
К сожалению, в официальном заявлении не объясняется, когда это делать await Task.Run. Есть краткое упоминание о Task.Run, но неясно. Суть в том, что awaitсамо по себе задача, связанная с процессором, не будет выполняться параллельно, поэтому такая работа должна выполняться через await Task.Run.
— ToolmakerSteve

2

Я думаю об этом так (и я думаю, что Microsoft тоже, если вы посмотрите https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ) # нити )

Async / await - это быстрый способ запустить некоторый код в основном потоке приложения с тем преимуществом, что код может приостанавливаться, когда у него нет работы, и возвращать фокус основному потоку, «просыпаться» в основном потоке, когда есть - результат, который нужно получить, а затем передать обработку обратно - как вы уже догадались - основному потоку. Думайте об этом как о операторе GOTO на основе событий в Basic, который может передавать управление взад и вперед определенной строке выполнения.

Напротив, поток - это отдельный поток выполнения, который может выполняться со своими собственными переменными и т. Д., Где - при наличии достаточного оборудования - выполнение происходит параллельно с основным потоком.

Если у вас есть приложение с графическим интерфейсом, которое будет загружать один файл, а затем делать что-то с этим файлом при его загрузке - я бы реализовал это с помощью метода async / await.

Однако, если вашему графическому интерфейсу необходимо загрузить 5000 файлов - я бы создал поток загрузки файлов, чтобы справиться с этим, поскольку основной поток графического интерфейса может зависнуть, пока выполнение передается для обработки загрузки файлов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.