Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does let!/do! always run the async object in a new thread?

Tags:

f#

From the wikibook on F# there is a small section where it says:

What does let! do?#

let! runs an async<'a> object on its own thread, then it immediately releases the current thread back to the threadpool. When let! returns, execution of the workflow will continue on the new thread, which may or may not be the same thread that the workflow started out on.

I have not found anywhere else in books or on the web where this fact (highlighted in bold) is stated.

Is this true for all let!/do! regardless of what the async object contains (e.g. Thread.Sleep()) and how it is started (e.g. Async.Start)?

Looking in the F# source code on github, I wasn't able to find the place where a call to bind executes on a new (TP) thread. Where in the code is the magic happening?

like image 434
kasperhj Avatar asked Oct 19 '22 09:10

kasperhj


1 Answers

Which part of that statement do you find surprising? That parts of a single async can execute on different threadpool threads, or that a threadpool thread is necessarily being released and obtained on each bind?

If it's the latter, then I agree - it sounds wrong. Looking at the code, there are only a few places where a new work item is being queued on the threadpool (namely, the few Async module functions that use queueAsync internally), and Async.SwitchToNewThread spawns a non-threadpool thread and runs the continuation there. A bind alone doesn't seem to be enough to switch threads.

The spirit of the statement however seems to be about the former - no guarantees are made that parts of an async block will run on the same thread. The exact thread that you run on should be treated as an implementation detail, and when you yield control and await some result, you can be pretty sure that you'll land on a different thread at least some of the time.

like image 53
scrwtp Avatar answered Oct 22 '22 23:10

scrwtp