使用 Dispatcher.Invoke 更新 UI 时遇到问题

发布于 2024-11-01 02:05:56 字数 956 浏览 3 评论 0原文

我正在开发一个基于插件的 WPF 应用程序。插件使用多个线程并行加载。其中一个插件是使用 WPF RibbonWindow 的 UI 插件。我正在尝试将插件 A 中的 RibbonTab 添加到 UI 插件中。

由于调用线程不拥有 RibbonWindow,因此我在 RibbonWindow 上使用 Dispatcher.Invoke。不幸的是,委托内部的代码永远不会被调用。应用程序仍具有响应能力,但未添加选项卡。

我是否可以从另一个插件访问 UI 线程? 我是否可以拥有一个可以在整个应用程序中保持活动状态的线程,以便我使用该线程在 RibbonWindow 上进行操作?

 System.Threading.ThreadStart start = delegate()
        {
            log.Debug(Thread.CurrentThread.ManagedThreadId);

            if (!this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,  (ThreadStart)delegate() {
                    log.Debug(Thread.CurrentThread.ManagedThreadId);
                    ribbonRoot.Items.Add(myRibbonTab);
                });
            }
            else {
                log.Debug("We have access add directly.");
            }

        };

        new Thread(start).Start();

如果您需要任何其他信息,请告诉我。

谢谢。

I am working on a plugin based WPF Application. The plugins are loaded parallely using multiple threads. One of the plugins is a UI plugin that uses a WPF RibbonWindow. I am trying to add a RibbonTab from Plugin A to the UI plugin.

Since the calling thread does not own the RibbonWindow, I am using the Dispatcher.Invoke on the RibbonWindow. Unfortunately the code inside the delegate is never being called. The application is still responsive, but the tab is not being added.

Is there anyway I can access the UI thread from another plugin?
Can I have a thread that can be kept alive all through my application, for me to use that Thread for operating on the RibbonWindow?

 System.Threading.ThreadStart start = delegate()
        {
            log.Debug(Thread.CurrentThread.ManagedThreadId);

            if (!this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,  (ThreadStart)delegate() {
                    log.Debug(Thread.CurrentThread.ManagedThreadId);
                    ribbonRoot.Items.Add(myRibbonTab);
                });
            }
            else {
                log.Debug("We have access add directly.");
            }

        };

        new Thread(start).Start();

Please let me know if you need any additional information.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我要还你自由 2024-11-08 02:05:56

您需要 Application.Current.Dispatcher 在 UI 线程上调用它。

顺便说一句:你为​​什么要转换到 ThreadStart? (不重要,只是好奇)

You need the Application.Current.Dispatcher to invoke it on the UI thread.

btw: Why are you casting to ThreadStart? (not important, just curious)

最丧也最甜 2024-11-08 02:05:56

如果您只想添加功能区选项卡,则无需为其启动线程(您已经将其分派到 UI 线程),除非您想在该线程上执行更多操作。即使如此,使用 ThreadPool 而不是创建新线程可能会更好。无论如何,在这样的场景中,我通常通过插件接口将 Dispatcher 从主窗口传递到插件,而不是直接访问 Application.Current.Dispatcher。使其更加封装,并且您可以在单元测试中更好地控制它。

If you just want to add the ribbon tab you don't need to start a thread for it (you are already dispatching it to the UI thread) unless there is more you want to do on the thread. Even then it might be better to use the ThreadPool instead of creating a new thread. Any way, in scenarios like this I usually pass the Dispatcher from the main window to the plugin via the plugin interface instead of directly accessing the Application.Current.Dispatcher. Makes it more encapsulated and you have better control over it in unit tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文