Can/Does WPF have multiple GUI threads?

后端 未结 1 1563
温柔的废话
温柔的废话 2020-11-30 23:11

Can/Does WPF have multiple GUI threads? Or does it always only have one GUI thread (even if I have multiple windows/dialogs)?

I\'m asking because I have events comin

1条回答
  •  一整个雨季
    2020-11-30 23:32

    Based on the link in the first answer I did some verification on my own. I'd like to share the results here. First of all:

    There can be multiple GUI threads (and therefor multiple Dispatcher instances).

    However:

    Simply creating a new window (modal or not) does not create a new GUI thread. One needs to create the thread explicitly (by creating a new instance of Thread).

    Note: Instead of using separate threads, modal dialogs are likely being realized by using Dispatcher.PushFrame() which blocks the caller of this method while still allowing events to be dispatched.

    I've created a simple WPF class (again, based on the link from the first answer) to verify all this stuff. I share it here so you can play around with it a little bit.

    MainWindow.xaml:

    
      
        
          
          
        
        
          
          
        
        

    MainWindow.xaml.cs:

    using System;
    using System.Threading;
    using System.Windows;
    using System.Windows.Media;
    
    namespace WindowThreadingTest {
      /// 
      /// Interaction logic for MainWindow.xaml
      /// 
      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");
            }
          }));
        }
      }
    }
    

    0 讨论(0)
提交回复
热议问题