How does one code an asynchronous WPF (or Windows Forms) event handler in F#? Specifically, is there any coding pattern that approximates C# 5\'s async and await?
He
Tomas correctly points out that if you can convert the slow method to be asynchronous, then let! and Async.StartImmedate work beautifully. That is preferred.
However, some slow methods do not have asynchronous counterparts. In that case, Tomas's suggestion of Async.AwaitTask works too. For completeness I mention another alternative, manually managing the marshalling with Async.SwitchToContext.
Async.AwaitTask a new Task
let btn_Click (sender : obj) e =
let btn = sender :?> Button
btn.IsEnabled <- false
async {
try
try
let prev = btn.Content :?> int
let! next = Task.Run(fun () -> incrementSlowly prev) |> Async.AwaitTask
btn.Content <- next
with ex -> btn.Content <- ex.Message
finally
btn.IsEnabled <- true
}
|> Async.StartImmediate
Manually manage thread context
let btn_Click (sender : obj) e =
let btn = sender :?> Button
btn.IsEnabled <- false
let prev = btn.Content :?> int
let uiContext = SynchronizationContext.Current
async {
try
try
let next = incrementSlowly prev
do! Async.SwitchToContext uiContext
btn.Content <- next
with ex ->
do! Async.SwitchToContext uiContext
btn.Content <- ex.Message
finally
btn.IsEnabled <- true
}
|> Async.Start