'Deadlock when creating WPF window in a thread

I am creating a new window in a thread in .Net Framework 4.8 WPF application. Most of time it works. However sometimes it hangs even when the app starts. The dispatcher in the main thread and the dispatcher in the new thread wait each other.

You can refer to the following window to check threads.

Threads window

The following is the entire .cs code to reproduce the phenomenon. 'NewWindow' is a class derived from 'System.Windows.Window' and it does not have to have anything in it to reproduce the phenomenon(For clarification I also put code for 'NewWindow' at the end of this question).

using System;
using System.Threading;
using System.Windows;
using System.Windows.Interop;

namespace WindowCreateTest
{
  public partial class MainWindow : Window
  {
    NewWindow newWindow = null;
    Thread uiThread = null;
    public MainWindow()
    {
      InitializeComponent();
    }
    public void ShowNewWindow(IntPtr handle)
    {
      uiThread = new Thread(() =>
      {
        Thread.CurrentThread.Name = "ShowNewWindow Thread";

        if (newWindow == null)
          newWindow = new NewWindow();

        WindowInteropHelper helper = new WindowInteropHelper(newWindow);
        helper.Owner = handle;

        newWindow.Show();

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

      uiThread.SetApartmentState(ApartmentState.STA);
      uiThread.Start();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      var h = new WindowInteropHelper(this).Handle;
      ShowNewWindow(h);
    }
  }
}

You might wonder why I'm creating a new window in a newly created thread not in a main thread. The reason is that, this code is used in MAF(Managed Add-ins and Extensibility Framework or System.AddIn) dlls which is activated in an external process.

WindowInteropHelper helper = new WindowInteropHelper(newWindow);
helper.Owner = handle;

The reason I put the above two lines is

  1. to make 'NewWindow' minimized when I minimize 'MainWindow'
  2. to make 'NewWindow' always be placed over 'MainWindow'.

And I guess this is the root cause of the deadlock.

using System.Windows;

namespace WindowCreateTest
{
  public partial class NewWindow : Window
  {
    public NewWindow()
    {
      InitializeComponent();
    }
  }
}

Thank you for reading and any advice will be welcomed and appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source