6

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?

kasperhj
  • 10,052
  • 21
  • 63
  • 106

2 Answers2

3

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.

scrwtp
  • 13,437
  • 2
  • 26
  • 30
  • I have updated my question to clarify a bit, but it's the latter. When I read it, I interpreted "let! runs an async object on its own thread" unambiguously as "let! runs the async object in a _new_ (TP) thread" which is probably not what it means. Good to learn that I was not alone in perceiving it that way. – kasperhj Jun 18 '15 at 07:15
1

No. An async operations might execute synchronously on the current thread, or it might wind up completing on a different thread. It depends entirely on how the async API in question is implemented.

See Do the new C# 5.0 'async' and 'await' keywords use multiple cores? for a decent explanation. The implementation details of F# and C# async are different, but the overall principles are the same.

The builder that implements the F# async computation expression is here.

Community
  • 1
  • 1
latkin
  • 16,402
  • 1
  • 47
  • 62