Вопрос

Как бы вы реализовали что-то, что работает аналогично ключевому слову Async CTP await?Существует ли простая реализация, которая работает как await во всех случаях, или же await требует разных реализаций для разных сценариев?

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

Решение

await всегда включает в себя одно и то же преобразование, но это довольно болезненное.Часть кода await библиотека не слишком сложна, но сложность заключается в том, что компилятор создает для вас конечный автомат, позволяя продолжить переход обратно в нужное место.

Возможно , что из-за моего хакерского использования блоков итератора (yield return) вы могли подделать что-то подобное ... но это было бы довольно некрасиво.

Несколько недель назад я провел веб-семинар DevExpress о том, что компилятор делает за кулисами -который показывает декомпилированный код из пары примеров, а также объясняет, как компилятор создает задачу для возврата и что должен делать «ожидающий».Это может быть вам полезно.

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

Новое ключевое слово await имеет семантику, аналогичную существующему ключевому слову yield return, в том смысле, что они оба заставляют компилятор генерировать для вас конечный автомат стиля продолжения. Таким образом, можно что-то взломать вместе, используя итераторы, которые имеют примерно такое же поведение, что и Async CTP.

Вот как это будет выглядеть.

родовое слово

Поскольку yield return генерирует код IEnumerable, наша сопрограмма должна возвращать код IEnumerable. Вся магия происходит внутри метода AsyncHelper.Invoke. Это то, что запускает нашу сопрограмму (маскирующуюся под взломанный итератор). Особое внимание уделяется тому, чтобы итератор всегда выполнялся в текущем контексте синхронизации, если он существует, что важно при попытке смоделировать, как await работает в потоке пользовательского интерфейса. Это достигается за счет синхронного выполнения первого кода MoveNext и последующего использования кода SynchronizationContext.Send для выполнения остальной части рабочего потока, который также используется для асинхронного ожидания отдельных шагов.

родовое слово

Все, что касалось TaskCompletionSource, было моей попыткой воспроизвести способ, которым await может "возвращать" значение. Проблема в том, что сопрограмма должна фактически возвращать код сгенерированного кода, поскольку это не что иное, как взломанный итератор. Поэтому мне нужно было придумать альтернативный механизм для захвата возвращаемого значения.

Здесь есть некоторые очевидные ограничения, но я надеюсь, что это дает вам общее представление. Он также демонстрирует, как CLR может иметь один обобщенный механизм для реализации сопрограмм, для которых IEnumerable и await будут использоваться повсеместно, но по-разному для обеспечения соответствующей семантики.

Существует несколько реализаций и примеров сопрограмм, сделанных из итераторов (yield).

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

Структура MindTouch DReAM реализует сопрограммы поверх шаблона Iterator, который функционально очень похож на Async /Жду:

родовое слово

против

родовое слово

Result - это версия кода Task для DReAM.DLL-файлы фреймворка работают с .NET 2.0+, но для их создания вам потребуется 3.5, поскольку в наши дни мы используем синтаксис 3.5.

Билл Вагнер из Microsoft написал статью в журнале MSDN о том, каквы можете использовать библиотеку параллельных задач в Visual Studio 2010 для реализации асинхронного поведения без добавления зависимости от асинхронного ctp.

Он широко использует Task и Task<T>, что также дает дополнительное преимущество, заключающееся в том, что после выхода C # 5 ваш код будет хорошо подготовлен для использования async и await.

Насколько я понимаю, основные различия между yield return и await заключаются в том, что await может явно возвращать новое значение в продолжение.

родовое слово

в то время как с yield return вам нужно будет выполнить то же самое по ссылке.

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