Вопрос

Я читал записи в блоге Эрика Липперта об асинхронности в C # 5 (часть 4 это особенно актуально) и наблюдал за выступлением Андерса PDC10 на эту тему, и мне неясно, как возобновляются продолжения из асинхронных методов в однопоточном контексте.

В обоих источниках обсуждается использование асинхронных методов в однопоточном цикле пользовательского интерфейса для повышения скорости реагирования, и в примере Андерса он упоминает, что когда асинхронная задача завершается, ее продолжение планируется путем добавления сообщения в перекачку сообщений.

Действительно ли асинхронный метод знает, что ему нужно выполнить то, что кажется специфичным для контекста действием, или это было упрощением?

В более общем плане, как можно выполнить возобновление из асинхронных методов в однопоточном контексте?Существует ли требование для планирования в рамках одного потока?

Это было полезно?

Решение

Продолжение задачи знает, где должно быть запланировано продолжение - например, «любой поток пула потоков» или «поток пользовательского интерфейса».

Это поведение определяется «ожиданием», однако, на самом деле это не является частью того, за что отвечает компилятор C#. Компилятор просто вызывает BeginAwait и проходит в продолжении; Awaiter возвращает логическое значение, указывающее, выполнила ли задача синхронно, или абонент должен вернуться и позволить продолжению происходить асинхронно.

Итак, на данный момент это решение принимается в ожидании, возвращенном TaskEx - но я не удивлюсь, увидев, что все это связано с Task в итоге. Это может вытекать в контекст синхронизации, который знает, как следует обрабатывать дальнейшие действия.

Я не совсем уверен, что искренне Однопоточный контекст, который вы рассматриваете ... или вы думаете о ситуации, когда основная часть работы должна произойти в одном потоке, но другие потоки могут быть задействованы для асинхронного бита (например, когда получен пакет HTTP , обрабатывается в потоке порта IO завершения, и в ответ обрабатывается Вернуться в нить пользовательского интерфейса)?

Другие советы

Ответ Джона, конечно, великолепен;Я подумал, что просто добавлю еще кое-что.

Рассмотрим приложение WinForms с одной кнопкой в форме, которая запускает код при нажатии на кнопку.

Что происходит, когда вы нет нажимаешь на кнопку?Ничего.Процесс существует, код запущен, но, похоже, он ничего не делает.Фактически, что он делает, так это обрабатывает сообщения в потоке пользовательского интерфейса и определяет, что ни одно из них не является интересным, но не похоже, что он делает что-то интересное.

Когда вы нажимаете на кнопку, внезапно одно из этих сообщений становится интересным, и насос сообщений знает, что когда он видит это событие click, он должен запустить некоторый код.Так оно и есть.

Сценарий асинхронности в одном потоке точно такой же.Продолжение - код "что делать после завершения задачи" фактически является "обработчиком события" события "задача завершена".Когда задача завершается, она "нажимает кнопку" и помещает сообщение в очередь сообщений потока пользовательского интерфейса.Не имеет значения, делает ли это из потока пользовательского интерфейса, или из потока завершения ввода-вывода, или что-то еще.Когда поток пользовательского интерфейса приступает к обработке этого сообщения, он вызывает продолжение.Точно так же, как когда поток пользовательского интерфейса приступает к обработке нажатия кнопки, он вызывает обработчик нажатия кнопки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top