Reputation: 2354
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
Upvotes: 3
Views: 193
Reputation: 12687
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
.
Upvotes: 1