How does F#'s async really work?

Viewed 6723

I am trying to learn how async and let! work in F#. All the docs i've read seem confusing. What's the point of running an async block with Async.RunSynchronously? Is this async or sync? Looks like a contradiction.

The documentation says that Async.StartImmediate runs in the current thread. If it runs in the same thread, it doesn't look very asynchronous to me... Or maybe asyncs are more like coroutines rather than threads. If so, when do they yield back an forth?

Quoting MS docs:

The line of code that uses let! starts the computation, and then the thread is suspended until the result is available, at which point execution continues.

If the thread waits for the result, why should i use it? Looks like plain old function call.

And what does Async.Parallel do? It receives a sequence of Async<'T>. Why not a sequence of plain functions to be executed in parallel?

I think i'm missing something very basic here. I guess after i understand that, all the documentation and samples will start making sense.

6 Answers

Lots of great detail in the other answers, but as I beginner I got tripped up by the differences between C# and F#.

F# async blocks are a recipe for how the code should run, not actually an instruction to run it yet.

You build up your recipe, maybe combining with other recipes (e.g. Async.Parallel). Only then do you ask the system to run it, and you can do that on the current thread (e.g. Async.StartImmediate) or on a new task, or various other ways.

So it's a decoupling of what you want to do from who should do it.

The C# model is often called 'Hot Tasks' because the tasks are started for you as part of their definition, vs. the F# 'Cold Task' models.

Related