Wpf F#Async.SwitchToContext与Dispatcher.Invoke
这两个函数(Wpf F#Async.SwitchToContext与Dispatcher.Invoke,wpf,asynchronous,f#,Wpf,Asynchronous,F#,这两个函数(doSync和postToUI)是否在(WPF)UI线程上执行相同的计算 还是有细微的区别 我的问题不是关于编码风格,而是关于幕后实际发生的事情 open System.Threading open System.Windows.Threading let doSync (f:'a -> 'b) x = async{ do! Async.SwitchToContext SynchronizationContext.Current retur
doSync
和postToUI
)是否在(WPF)UI线程上执行相同的计算
还是有细微的区别
我的问题不是关于编码风格,而是关于幕后实际发生的事情
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
开放系统线程
打开System.Windows.Threading
设doSync(f:'a->'b)x=
async{do!async.SwitchToContext SynchronizationContext.Current
返回f x
}|>Async.RunSynchronously
让postToUI:('a->'b)->'a->'b=
乐趣f x->
Dispatcher.CurrentDispatcher.Invoke(new System.Func(fun()->fx),[| |]]
|>拆开
它们可能是一样的,这要看情况而定
Async.SwitchToContext
将使异步继续在SynchronizationContext.Post
上运行。它的发布目的完全取决于调用doSync
的上下文
WPF有一个消息泵系统——Dispatcher,它在主(UI)线程上调度工作单元
现在,postToUI
肯定会在dispatcher框架上运行委托。
如果从WPF上下文中调用doSync
,SynchronizationContext.Current
将是
DispatchersSynchronizationContext
。以及:
您可以看到,DispatcherSynchronizationContext
最终调用了Dispatcher.Invoke
因此,总结一下:
- 如果您处于WPF上下文中,
将调用doSync
李>Dispatcher.BeginInvoke
- 如果您不在WPF上下文中,
将调用当前服务器上的任何实现doSync
Post
李>SynchronizationContext
- 如果您在任一上下文中,
将调用调度程序。调用postToUI
由于
Invoke
阻塞直到返回,SwitchToContext
实际上使用了Post
,doSync
更多的是postToUI
,postToUI
更多的是doSync
,,因此,在WPF中,Post
调用也会以相同的方式阻塞,因为异步.RunSynchronously
?是的,它是阻塞的。另一个细微的区别是,BeginInvoke
不会立即运行,而是将其排队等待执行。
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);
}