Является async и ждут исключительно для асинхронного программирования на основе графического интерфейса?
Я читал о новых операторах async
и await
на С# и пытался выяснить, в каких обстоятельствах они могут быть полезны для меня. Я изучил несколько статей MSDN, и вот что я прочитал между строками:
Вы можете использовать async
для обработчиков событий Windows Forms и WPF, чтобы они могли выполнять длительные задачи, не блокируя поток пользовательского интерфейса, пока основная часть операции выполняется.
async void button1_Click(object sender, EventArgs e)
{
// even though this call takes a while, the UI thread will not block
// while it is executing, therefore allowing further event handlers to
// be invoked.
await SomeLengthyOperationAsync();
}
Метод с использованием await
должен быть async
, что означает, что использование любой функции async
где-то в вашем коде в конечном итоге заставляет все методы в вызывающей последовательности от обработчиков событий пользовательского интерфейса до тех пор, пока не будет использоваться async
, чтобы быть async
.
Другими словами, если вы создаете поток с обычной доброй старой точкой входа ThreadStart
(или консольным приложением с добрым старым static int Main(string[] args)
), то вы не можете использовать async
и await
, потому что в какой-то момент вам нужно будет использовать await
и сделать метод, который использует его async
, и, следовательно, в вызывающем методе вы также должны использовать await
и сделать это async
и так далее. Но как только вы достигнете точки ввода потока (или Main()
), нет вызывающего абонента, которому будет присвоен элемент await
.
Таким образом, вы не можете использовать async
и await
без использования графического интерфейса, который использует стандартные контуры сообщений WinForms и WPF. Я думаю, что все это действительно имеет смысл, поскольку MSDN заявляет, что программирование async
не означает многопоточность, но вместо этого используется свободное время потока пользовательского интерфейса; при использовании консольного приложения или потока с определяемой пользователем точкой входа потребуется многопоточность для выполнения асинхронных операций (если не используется совместимый цикл сообщений).
Мой вопрос в том, являются ли эти предположения точными?
Ответы
Ответ 1
Таким образом, вы не можете использовать async и ждать, не имея графического интерфейса, который использует стандартные контуры сообщений WinForms и WPF.
Это абсолютно не так.
В Windows Forms и WPF async
/await
имеет удобное свойство возвращаться к потоку пользовательского интерфейса, когда ожидаемая асинхронная операция завершена, но это не значит, что это единственная цель.
Если асинхронный метод выполняется в потоке пула потоков - например, в веб-службе - тогда продолжение (остальная часть асинхронного метода) будет просто выполняться в любом потоке пула потоков, при этом контекст (безопасность и т.д.) будет сохранен соответствующим образом. Это по-прежнему очень полезно для уменьшения количества потоков.
Например, предположим, что у вас есть веб-служба с высоким трафиком, которая в основном запрашивает запросы на другие веб-службы. Он проводит большую часть своего времени, ожидая других вещей, будь то из-за сетевого трафика или подлинного времени в другой службе (например, в базе данных). Вам не нужно много потоков для этого - но с блокировкой вызовов вы, естественно, получаете поток за запрос. С async/await вы получите очень мало потоков, потому что очень мало запросов на самом деле потребует какой-либо работы, выполненной для них в любой момент времени, даже если было много запросов "в полете".
Проблема заключается в том, что async/await наиболее легко демонстрируется с помощью кода пользовательского интерфейса, потому что все знают, что боль от использования фоновых потоков должным образом или слишком много работает в потоке пользовательского интерфейса. Это не значит, что это единственное место, в котором эта функция полезна, - далеко от нее.
Различные серверные технологии (например, MVC и WCF) уже поддерживают асинхронные методы, и я ожидаю, что другие последуют примеру.
Ответ 2
Метод с использованием await должен быть асинхронным, что означает, что использование любой функции async где-то в вашем коде в конечном итоге заставляет все методы в вызывающей последовательности от обработчиков событий пользовательского интерфейса до тех пор, пока асинхронный метод самого низкого уровня не будет асинхронным.
Не верно - методы, помеченные как async, просто означают, что они могут использовать await, но вызывающие их методы не имеют ограничений. Если метод возвращает Task
или Task<T>
, то они могут использовать ContinueWith
или что-нибудь еще, что вы могли бы сделать с задачами в 4.0
Хорошим примером, отличным от UI, является MVC4 AsyncController.
В конечном счете, async/await в основном связано с переписыванием компилятора, поэтому вы можете написать то, что похоже на синхронный код, и избегать всех обратных вызовов, как вы должны были сделать до добавления асинхронного/ожидаемого. Это также помогает с обработкой SynchronizationContext, полезной для сценариев с привязкой потоков (интерфейсы пользовательского интерфейса, ASP.NET), но даже без них она по-прежнему полезна. Main может всегда делать DoStuffAsync().Wait();
, например.:)
Ответ 3
Мой вопрос в том, являются ли эти предположения точными?
Нет.
Вы можете использовать async для обработчиков событий Windows Forms и WPF, чтобы они могли выполнять длительные задачи, не блокируя поток пользовательского интерфейса, пока основная часть операции выполняется.
True. Также верно для других приложений пользовательского интерфейса, включая Silverlight и Windows Store.
И также верно для ASP.NET. В этом случае поток HTTP-запроса не заблокирован.
Метод с использованием await должен быть асинхронным, что означает, что использование любой функции async где-то в вашем коде в конечном итоге заставляет все методы в вызывающей последовательности от обработчиков событий пользовательского интерфейса до тех пор, пока асинхронный метод самого низкого уровня не будет асинхронным.
Это наилучшая практика ( "async
полностью вниз" ), но это не требуется строго. Вы можете заблокировать результат асинхронной операции; многие люди предпочитают делать это в консольных приложениях.
обычная старая точка входа ThreadStart
Ну... Мне нужно принимать проблемы с "обычным добрым". Как я объясняю в своем блоге, Thread
- это самый худший вариант для фоновых операций.
Я рекомендую вам ознакомиться с описанием async
и await
и следить за async
/await
Часто задаваемые вопросы.
Ответ 4
- async-wait - это только оболочка для манипуляций с классами Task, которая является частью так называемой Tasks Parallel Library - TPL (опубликованной до технологии автоматического генерации кода с использованием async-ожидания).
- Таким образом, вы можете не использовать ссылки на элементы пользовательского интерфейса в async-wait.
- Обычно async-await является мощным инструментом для любых отношений с сетью и сервером, загружая ресурсы, sql. Он работает с интеллектуальными ожидающими данными с живым интерфейсом.
- Обычно приложение TPL: от простого цикла большого размера до нескольких этапов параллельных вычислений в сложных вычислениях на основе общих данных (ContinueWith и т.д.)