Я могу что-то упустить
Ты.
какая разница между деланием Task.Wait
и await task
?
Вы заказываете обед у официанта в ресторане. Через мгновение после того, как вы отдаете заказ, заходит друг, садится рядом с вами и начинает разговор. Теперь у вас есть два варианта. Вы можете игнорировать своего друга, пока задача не будет завершена - вы можете ждать, пока прибудет ваш суп, и больше ничего не делать, пока ждете. Или вы можете ответить своему другу, и когда ваш друг перестанет говорить, официант принесет вам ваш суп.
Task.Wait
блокирует, пока задача не завершена - вы игнорируете своего друга, пока задача не будет завершена. await
продолжает обрабатывать сообщения в очереди сообщений, а когда задача завершается, она помещает в очередь сообщение с надписью «забрать, где вы остановились после этого ожидания». Вы разговариваете со своим другом, и когда в перерыве происходит перерыв, прибывает суп.
Task
которое занимает 10 мс, фактически выполняло бы 10-часовую работуTask
в вашем потоке, таким образом блокируя вас на все 10 часов?Чтобы продемонстрировать ответ Эрика, вот код:
источник
//If you press Button2 now you won't see anything in the console until this task is complete and then the label will be updated!
" вводит в заблуждение. После нажатия кнопки сt.Wait();
обработчиком события нажатия кнопкиButtonClick()
невозможно нажать что-либо, а затем увидеть что-то в консоли и обновить метку «до тех пор, пока эта задача не будет выполнена», поскольку графический интерфейс завис и не отвечает, то есть любые щелчки или взаимодействия с графическим интерфейсом. не будучи ПОТЕРЯЛИ до завершения задания ожиданияt.Wait
будет блокировать основной поток, пока задача не будет завершена».Этот пример демонстрирует разницу очень четко. При использовании async / await вызывающий поток не блокирует и продолжает выполнение.
DoAsTask Output:
Выход DoAsAsync:
Обновление: улучшенный пример, показывающий идентификатор потока в выходных данных.
источник
Wait () приведет к запуску потенциально асинхронного кода синхронно. ждать не буду.
Например, у вас есть веб-приложение asp.net. UserA вызывает / getUser / 1 конечную точку. Пул приложений asp.net выберет поток из пула потоков (Thread1), и этот поток выполнит HTTP-вызов. Если вы сделаете Wait (), этот поток будет заблокирован до разрешения http-вызова. Пока он ожидает, если UserB вызывает / getUser / 2, тогда пулу приложений потребуется обслуживать другой поток (Thread2) для повторного вызова http. Вы только что создали (ну, на самом деле, извлекли из пула приложений) другой поток без причины, потому что вы не можете использовать поток 1, он был заблокирован функцией Wait ().
Если вы используете await в Thread1, то SyncContext будет управлять синхронизацией между вызовами Thread1 и http. Просто он будет уведомлять, как только http-вызов завершен. Между тем, если UserB вызывает / getUser / 2, то вы снова будете использовать Thread1 для выполнения http-вызова, потому что он был освобожден после того, как ожидают попадания. Тогда другой запрос может использовать его, даже дальше. После завершения http-вызова (user1 или user2) Thread1 может получить результат и вернуться к вызывающей стороне (клиенту). Тема 1 использовалась для нескольких задач.
источник
В этом примере не так много, практически. Если вы ожидаете задачу, которая возвращается в другой поток (например, вызов WCF) или передает управление операционной системе (например, File IO), await будет использовать меньше системных ресурсов, не блокируя поток.
источник
В приведенном выше примере вы можете использовать «TaskCreationOptions.HideScheduler» и значительно изменить метод «DoAsTask». Сам метод не является асинхронным, как это происходит с «DoAsAsync», потому что он возвращает значение «Задача» и помечается как «асинхронный», создавая несколько комбинаций, это то, что он дает мне точно так же, как при использовании «async / await» :
источник