WPF是否可以有多个GUI线程?

| WPF是否可以有多个GUI线程?还是总是只有一个GUI线程(即使我有多个Windows /对话框)? 我问是因为我有来自其他线程的事件,并且希望在GUI线程中处理它们(因为我需要根据事件来修改主窗口的控件)。 顺便说一句:我知道我需要为此使用一个“ 0”对象。因此,我可以改问一下我的问题:WPF中的所有GUI元素是否总是只有一个“ 0”对象?
已邀请:
根据第一个答案中的链接,我自己进行了一些验证。我想在这里分享结果。首先: 可以有多个GUI线程(因此有多个“ 0”实例)。 然而: 仅仅创建一个新窗口(无论是否模态)都不会创建新的GUI线程。需要显式创建线程(通过创建creating3ѭ的新实例)。 注意:可以使用Dispatcher.PushFrame()来实现模态对话框,而不是使用单独的线程,该对话框会阻止此方法的调用者,同时仍允许分派事件。 我创建了一个简单的WPF类(同样,基于第一个答案的链接)来验证所有这些内容。我在这里分享它,以便您可以尝试一下。 MainWindow.xaml:
<Window x:Class=\"WindowThreadingTest.MainWindow\"
        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
        Width=\"250\" Height=\"130\">
  <StackPanel>
    <StackPanel Orientation=\"Horizontal\">
      <TextBlock Text=\"Thread\'s ID is \"/>
      <TextBlock x:Name=\"m_threadId\"/>
    </StackPanel>
    <StackPanel Orientation=\"Horizontal\">
      <TextBlock Text=\"Thread\'s threading apartment is \"/>
      <TextBlock x:Name=\"m_threadTA\"/>
    </StackPanel>
    <Button Click=\"OnCreateNewWindow\" Content=\"Open New Window\"/>
    <Button Click=\"OnAccessTest\" Content=\"Access Test\"/>
  </StackPanel>
</Window>
MainWindow.xaml.cs:
using System;
using System.Threading;
using System.Windows;
using System.Windows.Media;

namespace WindowThreadingTest {
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window {
    private static uint s_windowNumber = 0;

    private readonly MainWindow m_prevWindow;

    public MainWindow() : this(null) { }

    public MainWindow(MainWindow prevWindow) {
      InitializeComponent();

      this.m_prevWindow = prevWindow;

      this.Title = String.Format(\"Window {0}\", ++s_windowNumber);

      Thread thread = Thread.CurrentThread;
      this.m_threadId.Text = thread.ManagedThreadId.ToString();
      this.m_threadTA.Text = thread.GetApartmentState().ToString();
    }

    private void OnCreateNewWindow(object sender, RoutedEventArgs e) {
      CreateNewWindow(true, false, true);
    }

    private void CreateNewWindow(bool newThread, bool modal, bool showInTaskbar) {
      MainWindow mw = this;

      if (newThread) {
        Thread thread = new Thread(() => {
          MainWindow w = new MainWindow(this);
          w.ShowInTaskbar = showInTaskbar;

          if (modal) {
            // ShowDialog automatically starts the event queue for the new windows in the new thread. The window isn\'t
            // modal though.
            w.ShowDialog();
          } else {
            w.Show();
            w.Closed += (sender2, e2) => w.Dispatcher.InvokeShutdown();
            System.Windows.Threading.Dispatcher.Run();
          }
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

      } else {
        MainWindow w = new MainWindow(this);
        w.ShowInTaskbar = showInTaskbar;
        if (modal) {
          // Even modal dialogs run in the same thread.
          w.ShowDialog();
        } else {
          w.Show();
        }
      }
    }

    private void OnAccessTest(object sender, RoutedEventArgs e) {
      if (m_prevWindow == null) {
        return;
      }

      this.Background = Brushes.Lavender;
      try {
        m_prevWindow.Background = Brushes.LightBlue;
      } catch (InvalidOperationException excpt) {
        MessageBox.Show(\"Exception: \" + excpt.Message, \"Invalid Operation\");
      }
      m_prevWindow.Dispatcher.Invoke((Action)(() => m_prevWindow.Background = Brushes.Green));

      this.Dispatcher.Invoke((Action)(() => {
        try {
          m_prevWindow.Background = Brushes.Red;
        } catch (InvalidOperationException excpt) {
          MessageBox.Show(\"Exception: \" + excpt.Message, \"Invalid Dispatcher Operation\");
        }
      }));
    }
  }
}

要回复问题请先登录注册