Я прочитал где-то на Stackoverflow в комментарии следующую аналогию. Потому что в комментарии я не могу найти его легко, поэтому нет ссылки на него.
Предположим, вам нужно приготовить завтрак. Вы варите несколько яиц и курите хлеб.
Если вы закипание яйца, потом где-то в подпрограмме «Сварить яйцо», вам придется подождать, пока яйца варит
Синхронные будет то, что вы будете ждать, пока яйца не закончены кипения до начала подпрограммы "Тост".
Однако было бы более эффективным, если в то время как яйца отвариваются, вы не ждете, но начинаете поджаривать яйца. Затем вы ждете, пока кто-нибудь из них закончит, и продолжите процесс «Вареные яйца» или «Тост-хлеб», который заканчивается первым. Это асинхронно, но не параллельно. Это все еще один человек, который все делает.
Третий способ заключается в том, чтобы нанять повара, который кипит яйца, пока вы поджариваете хлеб. Это действительно одновременно: два человека что-то делают. Если вы действительно богаты, вы также можете нанять тостер, пока вы читаете газету, но, эй, мы не все живем в Аббатстве Даунтон ;-)
Назад к вопросу.
Nr 2: синхронно: основная нить выполняет всю работу. Этот поток возвращается после того, как яйцо кипит, прежде чем вызывающий может сделать что-нибудь еще.
Nr 1 не объявлен async. Это означает, что, хотя вы начинаете другой поток, который будет выполнять эту работу, ваш вызывающий абонент не может продолжать делать что-то еще, и, хотя вы можете этого сделать, вы просто не дожидаетесь, пока яйцо будет варено.
Третья процедура объявлена как асинхронная. Это означает, что, как только ожидание яйца начинается, ваш вызывающий может сделать что-то еще, например, поджаривать хлеб. Обратите внимание, что это работа, вся работа выполняется одним потоком.
Если ваш абонент будет ждать не делать ничего, кроме как ждать вас, это не будет очень полезно, если ваш вызывающий объект также не объявлен async. Это дало бы вызывающему абоненту возможность сделать что-то еще.
Обычно при использовании асинхр-ждать правильно, вы увидите следующее: - Каждая функция, которая объявлена асинхронной возвращает Task вместо пустоты и задачи < TResult> вместо TResult - Существует только одно исключение: обработчик события возвращает void вместо Task. - Каждая функция, вызывающая функцию async, должна быть объявлена как асинхронная, иначе использование async-ожидания не очень полезно - После вызова метода асинхронного сканирования вы можете начать поджаривать хлеб, пока яйцо кипятится.Когда хлеб поджарен, вы можете ждать яйца, или вы можете проверить, готов ли яйцо во время поджаривания, или, может быть, наиболее эффективным было бы ждать Task.WhenAny, чтобы продолжить финишное яйцо или тост или ждать Task. WhenAll, когда у вас нет ничего полезного, пока оба не закончены.
Надеюсь, что эта аналогия помогает
Первый работает асинхронно, второй не блокирует и блокирует. Результат возвращается синхронно, завернутый в Задачу. Третий почти такой же, как первый - 'async/await' просто упрощает процесс очистки, он не делает ничего асинхронным. Третий фактически имеет некоторый ненужный рывок, потому что результат фактически не используется внутри функции –
PS. Я не отправляю это как ответ, потому что есть много подобных вопросов. –
Примечание: это «асинхронная синхронизация»: бэкэнд-сервис ('GetBar') является в основном синхронным API, и вы открываете его через 'async'. Единственная причина, по которой это делается, заключается в том, чтобы освободить пользовательский интерфейс для рисования. Он не достигает более широкого набора целей «async»: у вас все еще есть ** ** нить, блокирующая результат - это просто не * исходный * поток. –