Подтвердить что ты не робот

Является 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 не означает многопоточность, но вместо этого используется свободное время потока пользовательского интерфейса; при использовании консольного приложения или потока с определяемой пользователем точкой входа потребуется многопоточность для выполнения асинхронных операций (если не используется совместимый цикл сообщений).

Мой вопрос в том, являются ли эти предположения точными?

4b9b3361

Ответ 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 и т.д.)