Одним из примеров, когда было бы хорошо иметь несколько уровней, было бы создание асинхронных контроллеров в среде MVC, такой как MonoRail или MS MVC. Конечная вещь, которая вызывает блокировку ввода-вывода, например SqlCommand из System.Data.SqlClient или какого-либо сокета, помещает операнд ввода-вывода в порт завершения ввода-вывода: http://msdn.microsoft.com/library/aa365198,, что позволяет сохранить кванты управляемого / неуправляемого потока для чего-то более полезного.
Если вы пишете классы, которые возвращают IAsyncResult, то вы не далеко от реализации сопрограмм. Вот хорошая статья о том, как асинхронное программирование может использоваться с сопрограммами: http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx.
Caliburn, инфраструктура WPF изначально поддерживает сопрограммы. Библиотека параллельных задач, выпущенная с .Net 4, дала своей задаче интерфейс IAsyncResult. [Если вы находитесь на уровне 3.5, вам может потребоваться создать собственную реализацию (их довольно просто сделать, просто реализуйте интерфейс).] Совместные подпрограммы - это способ использования перезаписей компилятора IEnumerable для передачи IAsyncResults в стек вещей, которые нужно сделать (как видно из «асинхронного менеджера»).
F # async (как видно в ответе с отрицательным голосом) использует монаду (такую же, как они попадают в CLR) для перемещения состояния асинхронного запроса из методов Begin * в End *. Оба компилятора это вложенные лямбда-выражения / SelectMany.