Reputation: 2865
I am new to F# Async workflows. Generally code and examples introducing this topic contain examples like the following (simplified):
let sleepWorkflow =
async{
printfn "Starting sleep workflow at %O" DateTime.Now.TimeOfDay
do! Async.Sleep 2000
printfn "Finished sleep workflow at %O" DateTime.Now.TimeOfDay
}
Async.RunSynchronously sleepWorkflow
I am trying to understand the need for do! Async.Sleep 2000
as opposed to do Threading.Thread.Sleep(2000)
in its place.
From my understanding, BOTH approaches will run the code synchronously at that point.
What is the difference (I assume there must be) and when should one be using one approach versus the other?
Upvotes: 2
Views: 289
Reputation: 243051
The difference is that using Thread.Sleep
blocks the current thread so that it cannot do anything else while Async.Sleep
creates a system timer, releases the current thread (so that it can do other things) and then (after the time elapses) acquires a thread again and runs the rest of the code.
This matters if you have a large number of async
workflows that run in parallel (because having a dedicated thread for each would be expensive) or when you are running code on the GUI thread (there is just one thread and you should not block it).
To better understand this, you can change the number of thread pool threads to 1 and try the following code using both synchronous and asynchronous blocking:
System.Threading.ThreadPool.SetMinThreads(1, 1)
System.Threading.ThreadPool.SetMaxThreads(1, 1)
for i in 1 .. 5 do
async { System.Threading.Thread.Sleep(1000)
printfn "Done" } |> Async.Start
for i in 1 .. 5 do
async { do! Async.Sleep(1000)
printfn "Done" } |> Async.Start
After running the first for
loop, you'll the "Done" messages will be printed with 1 second delays (because the one thread is repeatedly blocked for 1 second).
After running the second for
loop, you'll see "Done" messages printed all at once after 1 second. This is because the asynchronous waiting is not actually blocking the thread and so the 5 timers will all elapse and then use the 1 available thread to do the printing (which takes almost no time).
Upvotes: 8