wpf - F# Async.SwitchToContext 与 Dispatcher.Invoke

标签 wpf asynchronous f#

这两个函数(doSyncpostToUI)是否在 (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 上下文中调用 doSyncSynchronizationContext.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 实际上使用 PostdoSync 更像是 postToUI ,而postToUI更像是doSync

关于wpf - F# Async.SwitchToContext 与 Dispatcher.Invoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61227071/

相关文章:

c# - WPF 和 Workflow Foundation 不能一起工作

c# - 如何访问主窗体公共(public)属性 WPF

c# - 为什么 HttpClient 在随后使用 Polly 重试期间继续失败?

Java 6 线程输出不是异步的?

pointers - F# - 是否需要明确删除引用单元格?

f# - F# 中的惯用构造函数

c# - 为什么在 WPF 中将 BitmapSource 保存为 bmp、jpeg 和 png 时得到完全不同的结果

c# - 为 ListView 中的项目着色

swift - 异步中的 ActivityIndi​​cator - Swift

c# - 在 F# 中使用 SqlDataReader