An async block is an F# computation-expression construct for deferred asynchronous work. It suits long-running, I/O-bound, or CPU-heavy operations where efficient throughput matters. section 12.2.6 section 12.4
Unlike a hot task block, an async block is cold: creating it does not start execution. Start it explicitly with Async.Start, Async.RunSynchronously, or let! inside another async block. The computation can then be run repeatedly from the beginning, and cancellation is handled implicitly. section 12.2.6
Use the async block when its execution model fits the surrounding application:
- Await Async or converted Task values with let! and do!. section 12.2.6
- Convert .NET Task-returning APIs with Async.AwaitTask, and convert async computations back with Async.StartAsTask. section 12.2.6
- Prefer task blocks when broad .NET or C# interoperability and the newer standard abstraction matter; retain async blocks for their cold, repeatable workflow and implicit cancellation. section 12.2.6 section 12.4
Listing 12.5 Using the async {} block with interop for tasks
let writeToFileAsync fileName data = async { #1
do!
System.IO.File.AppendAllTextAsync(fileName, data)
|> Async.AwaitTask #2
let! data =
System.IO.File.ReadAllTextAsync fileName
|> Async.AwaitTask #2
return data.Length
} #1
A compact file-writing and file-reading workflow demonstrates async composition, Task conversion with Async.AwaitTask, and returning a computed result. section 12.2.6
