I'll only add that the do! notation doesn't have to be explicitly supported by the computation expression, because the same thing can be written using let! like this:
do! foo() // Using do!
let! _ = foo() // Equivalent using let!
In general let! us used when you have some function implemented using computation expressions and you want to call it from another computation expression of the same type. This means, that it is used for composing computation expressions. For async this composition means that you have a non-blocking asynchronous code and call it from another asynchronous workflow in some special way to make the call asynchronous.
The let! keyword allows you to do this and get some value as the result, while do! is a shortcut that you can use if the computation doesn't return anything.
A chapter from Real-world Functional Programming that discusses computation expressions (and also sequence expressions) is available as a free sample, so if you want to read a more detailed tutorial about computation expressions this may be a good source of infromation:
BTW: It should be possible to write the sample code in your question in a nicer way using the AwaitEvent primitive like this:
async {
let! _ = this.Loaded |> Async.AwaitEvent
do! Async.Sleep 200
for cmd in theDrawing do
do! this.Execute(cmd) } |> Async.StartImmediate
This means the same thing - it first waits until the Loaded event occurs, then it waits 200ms and then it does the rest of the work. This waiting is special (that's why we use let!/do!, because it doesn't bl
answered 2010-04-18T02:14:00.713