Async / Await vs Threads


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

2
Я думав, що Async / Await робить те саме, що new Thread(() => {Some Work}).Start();робить ?! чи не так?
Роман Рацкі 01.03.13

2
Ні. Ваше припущення невірно. Можливо, ви думаєте про Task.Run (TPL), який часто поєднується з Async / Await, але також не пов'язаний між собою і не повинен ним користуватися.
dtb

4
@dtb: Тож коли використовувати Async / Await і коли використовувати потоки ?. Я дуже розгублений щодо різниці між Task.Run, Thread.Start, Async / Await. Якщо ви могли б дати мені гарне пояснення, яке змушує мене зрозуміти відмінності між ними, я був би дуже вдячний
Роман Ратскі

2
Async / wait не створює або не використовує нитки.
WRAR

Відповіді:


78

чи може це повністю замінити старий спосіб використання теми?

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

здатний робити те, що коли-небудь Нитка може робити асинхронно?

Грубо. Очікуйте просто піклуватися про затримку, інакше це не робить нічого, що робить нитка. Вираз очікування , що знаходиться праворуч від ключового слова очікування, - це те, що робить роботу. В ідеалі він взагалі не використовує потік, він публікує запит драйвера, і як тільки драйвер завершує передачу даних, він генерує зворотний виклик повідомлення про завершення. Мережі - це найпоширеніший спосіб використання, затримки в сотні мілісекунд є загальними і неминучий побічний ефект послуг, що переходять з робочого столу чи локальної мережі в "хмару". Використання таких сервісів синхронно зробить інтерфейс користувача безвідмовним.

може використовуватися лише з деякими методами, такими як WebClient.DownloadStringAsync

Ні. Ви можете використовувати його з будь-яким методом, який повертає завдання. Методи XxxxAsync () - це лише попередньо підготовлені методи в рамках .NET для звичайних операцій, які потребують часу. Як і завантаження даних з веб-сервера.


4
У сучасному аспекті C #, який найкращий підхід для досягнення зворотних викликів Async на зовнішніх API?
bonCodigo

5
Описаний в останньому абзаці, використовуйте Завдання.
Ганс Пасант

Я б очікував, що те, що може зробити нитка, що неможливо зробити через програму async як приклад.
Саїд Неаматі

1
Чи можете ви розширити тему "Нитка може зробити ще багато корисних речей." Було б корисно розібратися в особливостях наданих потоків, які asyncне підходять.
Бенджон

1
Варто згадати await Task.Runдля роботи на процесорі. Якщо я правильно розумію, це іноді виконує те, що інакше було б створити нитку або фонового працівника.
ToolmakerSteve

15

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


Це як перший ресурс, який я прочитав про "Нитки та Async / Await", який є зрозумілим і стислим.
Арман Біматов

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, який може передавати керування вперед і назад певній лінії виконання.

На відміну від цього, потік - це окремий потік виконання, який може працювати з його власними змінними тощо, де - за умови достатнього обладнання - виконання відбувається паралельно основному потоку.

Якщо у вас є програма GUI, яка збирається завантажити один файл, а потім зробити щось із цим файлом після його завантаження - я реалізував би це за допомогою методу async / await.

Однак якщо вашому графічному інтерфейсу потрібно завантажити 5000 файлів - я б створив нитку для завантаження файлів, щоб обробити це, оскільки головний потік GUI може замерзнути, коли виконання передається для обробки завантаження файлів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.