Can/Does WPF have multiple GUI threads? Can/Does WPF have multiple GUI threads? multithreading multithreading

Can/Does WPF have multiple GUI threads?


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:

<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");        }      }));    }  }}