使用调度程序从工作线程修改 GUI 元素的正确方法?

发布于 2024-09-27 06:46:58 字数 664 浏览 4 评论 0原文

我在这里遇到了一个问题,我想从各个工作线程修改 GUI 元素。直到今天,我使用的方法虽然有效,但很可能是非常错误的。

最简单的情况涉及我的插件的 GUI,它在工作线程中执行某些操作,当该方法完成其工作时,它会调用我的回调。该回调方法是从同一线程处理的,因此它不能执行任何 GUI 工作。但是,当我的插件的 GUI 由我的主应用程序 GUI 显示时,我的插件 GUI 会缓存其 Dispatcher 引用 - 当我确实需要进行 GUI 更新(或者在本例中显示对话框)时,我会调用 Dispatcher.Invoke(.. .)。

像这样在我的插件中设置调度程序是否存在任何固有的危险?

今天,我对这种方法遇到了一个新问题。我的应用程序需要在我的插件中调用该方法来启动工作线程并显示一个对话框。如果我在打开插件的 GUI(缓存 Dispatcher 引用)之前调用该方法,则操作将失败,因为 Dispatcher 为空。我总是检查这一点以确保应用程序不会崩溃。但是,既然该对话框未显示,则无法继续进行必要的用户交互。

任何人都可以建议一种更好的方法来使用 Dispatcher 以确保我可以从主应用程序显示/修改插件的 GUI 元素吗?我现在唯一能想到的就是让我的主应用程序将其 Dispatcher 引用传递给我的插件加载器,将“SetDispatcher”方法添加到我的插件接口,然后让插件加载器为每个需要的插件调用此方法已加载。

I've got a bit of an issue here where I want to modify GUI elements from various worker threads. Until today, the method I was using worked, but it was most likely very incorrect.

The simplest case involves my plugin's GUI, which does something in a worker thread, and when that method completes its work, it calls my callback. That callback method is handled from the same thread, so it cannot do any GUI work. However, when my plugin's GUI is displayed by my main app GUI, my plugin GUI caches its Dispatcher reference -- when I do need to do GUI updates (or in this case, display a dialog), I call Dispatcher.Invoke(...).

Is there any inherent danger in setting the Dispatcher in my plugins like this?

Today, I have a new problem with this approach. My application needs to call that method in my plugin that launches the worker thread and displays a dialog. If I call the method before I open the plugin's GUI (which caches the Dispatcher reference), the operation will fail because the Dispatcher is null. I always check for that to make sure the app doesn't crash. However, now that the dialog isn't displayed, the necessary user interactions cannot proceed.

Can anyone suggest a better method for using the Dispatcher to ensure that I can display / modify a plugin's GUI elements from my main application? The only thing I can think of right now is to have my main application pass its Dispatcher reference to my plugin loader, add a "SetDispatcher" method to my plugin interface, and then have the plugin loader call this for every plugin that needs to be loaded.

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

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

发布评论

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

评论(2

靖瑶 2024-10-04 06:46:58

如果您的插件 GUI 在后台线程完成时必须存在,那么您应该确保插件 GUI 创建/实例化发生在您分离该后台进程之前。这样,插件 GUI 元素调度程序就会在异步任务完成之前由框架设置。

在更高的层面上(您可能能够解决这个问题,也可能无法解决这个问题),GUI 和后台发生的事情之间似乎存在一些不适当的耦合。

If your plugin's GUI must exist by the time the background thread finishes, you should probably make sure that the plugin GUI creation/instantiation happens before you spin off that background process. That way, the plugin GUI element(s) Dispatcher is set by the framework before your async stuff finishes.

At a higher level (you may or may not be able to address this), it seems like you've got some inappropriate coupling between the GUI and the stuff that's occurring in the background.

森林很绿却致人迷途 2024-10-04 06:46:58

目前,我发现一个很好的解决方案,无论是否合适,都是通过 MEF 导出主线程的 Dispatcher,然后允许所有插件导入它。这似乎是目前处理此类事情最干净的方法。

For now, I've found that a nice solution, appropriate or not, is to export the main thread's Dispatcher via MEF, and then allow all of the plugins to import it. It seems like the cleanest way to deal with this sort of thing right now.

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