These computation-expression builders are built on the compiler's runtime-async intrinsics (see docs/runtime-async.md). They are test fixtures and examples, not FSharp.Core APIs.
runtimeTask (RuntimeTaskBuilder.fs)
Produces hot Task<'T> and ValueTask<'T> values, like task { }. Source overloads turn tasks, custom awaitables and Async<'T> into started delegates, so Bind and MergeSources need no per-type overloads. and! starts every source before awaiting any of them.
async2 (Async2Builder.fs)
Produces cold, cancellable Async2<'T> computations. The cancellation token is threaded through the computation, checked between steps, and passed to cold sources such as Async<'T> and other async2 computations. and! starts the right source before awaiting the left.
asyncSeq2 (AsyncSeq2Builder.fs)
Produces IAsyncEnumerable<'T> using __runtimeAsyncSequence.
let!anddo!accept tasks, value tasks, custom awaitables,async2andAsynccomputations, andCancellationToken -> Taskfactories. Cold sources receive the enumeration's cancellation token.forandyield!accept bothseq<'T>andIAsyncEnumerable<'T>.- One driver enumerator runs nested
yield!sources in a loop, so deep recursion does not grow the call stack. - A
yield!in tail position (YieldFromFinal) hands off to the new source and releases the enumerator it came from. Ayield!that isn't in tail position keeps its parent enumerator until the nested source finishes. - A second
MoveNextAsync, or aDisposeAsync, while a move is pending throwsInvalidOperationException.
- RuntimeTasks.fs: the FSharp.Core
task { }tests, ported toruntimeTask. - EnumerableTests.fs and RuntimeAsyncEnumerableTests.fs:
asyncSeq2behavior, includingtry/with, cancellation and recursion. - RuntimeAsyncSequence.fs: a small
asyncSeq2usage and lifecycle example.