Are these two functions ( doSync and postToUI ) doing the same kind of evaluation on the (WPF) UI thread?
Or is there a subtle difference?
My question is less about coding style but more about what is actually happening behind the scene.
open System.Threading
open System.Windows.Threading
let doSync (f:'a -> 'b) x =
async{ do! Async.SwitchToContext SynchronizationContext.Current
return f x
} |> Async.RunSynchronously
let postToUI : ('a -> 'b) -> 'a -> 'b =
fun f x ->
Dispatcher.CurrentDispatcher.Invoke(new System.Func<_>(fun () -> f x), [||])
|> unbox
They could be the same, it depends.
Async.SwitchToContext will make the async continuations run on SynchronizationContext.Post. What it's posting to entirely depends on the context of the call to doSync.
WPF has a message pump system - the Dispatcher, which schedules units of work on the main (the UI) thread.
Now, postToUI will certainly run the delegate on a dispatcher frame.
If you call doSync from within a WPF context, SynchronizationContext.Current will be
DispatcherSynchronizationContext. And under the hood:
public override void Send(SendOrPostCallback d, Object state)
{
_dispatcher.Invoke(DispatcherPriority.Send, d, state);
}
public override void Post(SendOrPostCallback d, Object state)
{
_dispatcher.BeginInvoke(_priority, d, state);
}
you can see that DispatcherSynchronizationContext ends up calling Dispatcher.Invoke.
So, to summarise:
doSync will call
Dispatcher.BeginInvoke. doSync
will call whatever implements Post on the current
SynchronizationContext. postToUI
will call Dispatcher.Invoke.P.S.
Since Invoke blocks until return, and SwitchToContext actually uses Post, doSync is more postToUI, and postToUI is more doSync.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With