这两个函数(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
最佳答案
它们可能相同,这取决于。
Async.SwitchToContext
将使异步延续在 SynchronizationContext.Post
上运行。它发布到什么完全取决于调用 doSync
的上下文。
WPF 有一个消息泵系统 - Dispatcher,它在主(UI)线程上安排工作单元。
现在,postToUI
肯定会在调度程序框架上运行委托(delegate)。
如果您从 WPF 上下文中调用 doSync
,SynchronizationContext.Current
将是
DispatcherSynchronizationContext
。和 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);
}
您可以看到 DispatcherSynchronizationContext
最终调用了 Dispatcher.Invoke
。
总结一下:
- 如果您处于 WPF 上下文中,
doSync
将调用Dispatcher.BeginInvoke
。 - 如果您不在 WPF 上下文中,
doSync
将在当前调用任何实现Post
的东西同步上下文
。 - 如果您处于任一上下文中,
postToUI
将调用Dispatcher.Invoke
。
附言
由于 Invoke
阻塞直到返回,而 SwitchToContext
实际上使用 Post
,doSync
更像是 postToUI
,而postToUI
更像是doSync
。
关于wpf - F# Async.SwitchToContext 与 Dispatcher.Invoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61227071/