【问题标题】:Opening a WPF Window in another Thread from a Windows Forms App从 Windows 窗体应用程序在另一个线程中打开 WPF 窗口
【发布时间】:2010-10-18 07:01:26
【问题描述】:

好的,我应该先说我不确定这一定是处理这个问题的正确方法,但是......

基本上,我在 WPF 中创建了一个窗口,用于在我的应用程序中显示通知(有点像 Outlook 新邮件通知)。我想尝试在它自己的线程中显示这个窗口(它将来可能会做一些工作)。

我使用 WPF 创建了窗口,因为它在处理 AlwaysOnTop 和淡入淡出之类的事情时更好一些。

显示通知的应用程序是 3.5 Windows 窗体应用程序。我已经看到与 SOF: C# winforms startup (Splash) form not hiding 类似的示例,用于在不同的线程中显示表单,但是我无法使用 WPF 窗口启动新的消息循环。

我尝试在新线程中调用 Notification.Show(),但窗口从不显示。

  1. 是否可以在它自己的线程中显示这个 WPF?

  2. 为什么我看到一些资源说您不应该在单独的线程中显示任何 UI?

【问题讨论】:

    标签: c# wpf winforms multithreading


    【解决方案1】:

    您应该使用主 UI 线程显示通知,如果该窗口要执行任何工作,请在后台线程中运行该工作。您不应该使用多个线程来访问或创建 UI 对象,即使您不在线程之间共享这些对象也是如此。

    【讨论】:

    • 很公平,但为什么呢?我的意思是,为什么我不应该在多个线程中创建 UI 对象?我希望这个窗口在不影响用户当前工作的情况下加载和显示
    【解决方案2】:

    WPF Threading Model 对此有详细说明。寻找“多窗口,多线程”。

    基本上,你启动一个新线程,它会创建相关的窗口,然后调用

    System.Windows.Threading.Dispatcher.Run();
    

    为了在新线程上为该窗口运行调度程序。

    【讨论】:

    • 谢谢,这一行:System.Windows.Threading.Dispatcher.Run() 使我的表单显示在线程中。还没有完全理解,但是文章给了我一个方向,谢谢。有趣的是,文章说在不同线程上创建 UI 表单是完全合理的。
    • +1 不调用 Dipatcher.run 也是我的问题,没有它我的新窗口会闪烁并很快消失。
    • @MikeCole: Dispatcher.InvokeShutdown?
    • @ayssa:这很奇怪——谷歌缓存的版本可以工作,但原始版本不行。我现在已经将两者都包含在答案中。 (我现在很想删除这个答案,因为它基本上只是一个链接,但它已被接受。将编辑以提供更多信息。)
    • @ayssa:我希望这是一个暂时的现象......虽然现在答案中有额外的信息,但链接不那么重要了。
    【解决方案3】:
    1. 是否可以在它自己的线程中显示这个 WPF?

    当然。只需创建一个新的 STA 线程并从中创建并显示您的 Window。我已经将这种技术用于启动屏幕,因为主(UI)线程真的被束缚在做其他事情。由于我们使用的是第 3 方框架,我完全无法控制在 UI 线程上完成了多少工作。

    1. 为什么我看到一些资源说您不应该在单独的线程中显示任何 UI?

    可能是因为涉及额外的复杂性。如果您的一个Windows 想要将数据传递给另一个,您需要记住它们是在不同的线程上执行的。因此,每个都应该使用它的 Dispatcher 来编组对正确线程的调用。

    【讨论】:

    • 嗨,我已经在 STA 线程中尝试了新窗口,但是当我调用 Notification.Show() 时没有显示任何内容。
    • 您可能需要简化和发布最少的代码。这可能很简单,比如忘记启动线程;)
    猜你喜欢
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多