【问题标题】:WPF/threading: Dispatcher static vs Dispatcher on a control?WPF/线程:Dispatcher static vs Dispatcher 在控件上?
【发布时间】:2011-01-06 22:46:46
【问题描述】:

我对调度程序有点困惑。假设我在后台线程上进行某种长时间的操作。我想更新我知道我通过调度程序执行此操作的 ui 线程。我的问题是,我是否像这样静态调用调度程序: Dispatcher.BeginInvoke(mywork) ... 或者在我要更新的控件上:mytextbox.Dispatcher.BeginInvoke(mywork)

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    值得注意的是,调用Dispatcher.BeginInvoke不是静态调用:它是一个隐含的this.Dispatcher.BeginInvoke。如果您可以使用此调用,那么您很可能已经在控件或窗口中编写代码。在这种情况下,您可能可以安全地调用其中任何一个,因为大多数情况下每个应用程序都有一个 UI 线程。

    实际的静态调用将是 Dispatcher.CurrentDispatcher.BeginInvoke,这不是您想要调用的东西(请参阅我对 Hasan Khan 的回答的评论了解原因)。

    编辑:调用Application.Current.Dispatcher 不是一件坏事。 (并且,为了清楚起见,它是一个实例属性,而不是静态 - 在 Application 的静态/单例实例上调用。)此属性将返回创建应用程序的线程的调度程序,通常是线程UI 也是在上面创建的 - 所以Application.Current.Dispatcher 返回的调度程序与myWindow.Dispatcher 相同。

    静态调用Dispatcher.CurrentDispatcher(我警告过)为您调用它的线程返回一个调度程序。如果您从后台线程调用它,您将获得一个专门为该线程创建的新 Dispatcher - 这通常不是我们想要的。

    【讨论】:

    • 为什么使用Application.Current.Dispatcher是个坏主意?到目前为止,我在我的应用程序中使用它没有任何问题。它只需要调用Application().Run()
    • @Aphex:我已经回答为编辑,因为我无法将其放入评论中 - 但Application.Current.Dispatcher 没有任何问题(而且我没有说有)。 Application.Current.DispatcherDispatcher.CurrentDispatcher 的行为非常不同!
    • 在某些情况下使用 Application.Current.Dispatcher 是不安全的(尽管非常罕见),例如在 WinForms(或任何其他非 WPF)应用程序中托管 WPF 控件(Application.Current 为空)或在同一应用程序中具有多个 UI 线程(共享应用程序资源存在很多问题,但案例仍然相关)。因此最安全的方法是使用 control.Dispatcher
    【解决方案2】:

    首先我认为了解Dispatcher 不是为处理大型后台操作而设计的很重要。它旨在对对象的 UI 线程上的工作进行排队。这是一篇关于 .NET 线程模型和Dispatcher 的有价值的 MSDN 文章:

    说实现Dispatcher.BeginInvoke 方法的标准方式是在控件上调用它:

    startStopButton.Dispatcher.BeginInvoke(
        DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
    );
    

    希望有帮助!

    【讨论】:

      【解决方案3】:

      虽然在大多数情况下使用DispatcherObject.Dispatcher(所有依赖对象和控件都继承自DispatcherObject等)或Application.Current.Dispatcher是正确的做法,因为通常只有一个UI线程,可以有多个UI线程,不同的窗口可以使用不同的调度器。在这种情况下,使用其调度程序更新控件很重要。它存储在其Dispatcher 属性(继承自DispatcherObject)、此窗口中的任何其他控件以及窗口本身中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-29
        • 1970-01-01
        • 2011-09-14
        • 2023-03-05
        • 2022-10-18
        相关资源
        最近更新 更多