Ich möchte nur hinzufügen, dass die do!
Notation muss nicht explizit durch den Berechnungsausdruck unterstützt werden, denn dasselbe kann auch mit let!
wie diese:
do! foo() // Using do!
let! _ = foo() // Equivalent using let!
Im Allgemeinen let!
wird verwendet, wenn Sie eine Funktion mit Hilfe von Berechnungsausdrücken implementiert haben und diese von einem anderen Berechnungsausdruck desselben Typs aus aufrufen möchten. Das bedeutet, dass sie zum Zusammensetzen von Berechnungsausdrücken verwendet wird. Für async
este Zusammensetzung bedeutet, dass Sie einen nicht-blockierenden asynchronen Code haben und ihn von einem anderen asynchronen Workflow aus auf eine spezielle Weise aufrufen, um den Aufruf asynchron zu machen.
En let!
Schlüsselwort können Sie dies tun und einen Wert als Ergebnis erhalten, während do!
ist eine Abkürzung, die Sie verwenden können, wenn die Berechnung kein Ergebnis liefert.
Ein Kapitel aus Real-world Functional Programming, das Berechnungsausdrücke (und auch Sequenzausdrücke) behandelt, ist als kostenloses Beispiel verfügbar. Wenn Sie also ein ausführlicheres Tutorial über Berechnungsausdrücke kann dies eine gute Informationsquelle sein:
BTW: Es sollte möglich sein, den Beispielcode in Ihrer Frage auf eine schönere Weise zu schreiben, indem man die AwaitEvent
primitiv wie diese:
async {
let! _ = this.Loaded |> Async.AwaitEvent
do! Async.Sleep 200
for cmd in theDrawing do
do! this.Execute(cmd) } |> Async.StartImmediate
Das bedeutet dasselbe - es wird zunächst gewartet, bis die Loaded
Ereignis eintritt, wartet es 200ms und erledigt dann den Rest der Arbeit. Diese Warten ist speziell (deshalb verwenden wir let!
/ do!
weil es den Thread während des Wartens nicht blockiert).