Какая связь между шаблоном async/await и продолжениями?

Мне интересно, какая связь между шаблоном async/await (известным из Scala, F#, C# и т. д.) и продолжениями:

  • Является ли паттерн async/await ограниченным набором полномасштабных продолжений? (Если да, то как продолжения более выразительны?)
  • Являются ли продолжения лишь одним из возможных способов реализации async/await? (Если это правда, какие другие подходы к реализации существуют?)
  • Или async/await и продолжения просто ортогональные понятия, где единственная общность заключается в том, что они оба допускают некоторую абстракцию потока управления/потока данных?

comment
Связано: stackoverflow.com/q/22852251/1768303   -  person noseratio    schedule 04.04.2014


Ответы (1)


Я бы сказал, что связь между ними такова: async-await — это техника, которую используют языки программирования, чтобы вы могли писать код, который выглядит синхронно (например, без явных делегатов продолжения), но на самом деле выполняется асинхронно. Это достигается созданием объекта, представляющего текущее состояние выполнения функции, и его регистрацией как продолжение ожидаемой операции.

Короче говоря, async-await использует продолжения.

Является ли паттерн async/await ограниченным набором полномасштабных продолжений? (Если да, то как продолжения более выразительны?)

Ты мог сказать это. Продолжения — это более общая концепция, async-await просто использует их для достижения асинхронности.

Например, в стиле передачи продолжений вы можете реализовать обработку исключений, используя два продолжения. для каждой операции: один для случая успеха и один для случая отказа. Такое использование продолжений не имеет ничего общего с async-await (вам пришлось бы писать каждое продолжение явно, возможно, как лямбду).

Являются ли продолжения лишь одним из возможных способов реализации async/await? (Если это правда, какие другие подходы к реализации существуют?)

Я бы сказал, что концепция продолжения занимает центральное место в async-await.

Основная идея async-await состоит в том, чтобы остановить выполнение функции на данный момент и возобновить ее позже. И для этого вам нужен какой-то объект, который можно использовать для этого возобновления. Именно это и есть продолжение.

person svick    schedule 03.04.2014
comment
Кроме того, ContinueWith позволяет возобновить асинхронный метод. Это было бы невозможно, например, с необработанными потоками, потому что вы не можете получить обратный вызов, когда он выходит. Вы можете только ждать. - person usr; 03.04.2014
comment
Хотя продолжение не обязательно связано с асинхронным выполнением. Еще один пример — yield, первоначальная цель которого не имеет ничего общего с асинхронностью. - person noseratio; 03.04.2014
comment
@Noseratio Да, это часть того, что я пытался сказать. - person svick; 03.04.2014
comment
@свик. Спасибо за Ваш ответ! Не могли бы вы прокомментировать, как async/await использует продолжения? (Например, он просто подключается к сдвигу/сбросу внизу или происходит больше магии?) - person soc; 04.04.2014
comment
@soc Я думаю, что async-await не имеет ничего общего с продолжениями с разделителями, оно просто использует обычные продолжения. - person svick; 04.04.2014