3

I am working on a WPF application that I need to completely shut down when the main window is closed. There is another window that can be opened by the program that I open and run like this (variable names are changed, but here is the logic):

private void NewWindowButton_Click(object sender, RoutedEventArgs e) {
    Thread WindowThread = new Thread(new ThreadStart(NewWindowThread));
    WindowThread.SetApartmentState(ApartmentState.STA);
    WindowThread.IsBackground = true;
    WindowThread.Start();
}

private void NewWindowThread() {
    var NewWindow = new NewWindow();
    NewWindow.Show();
    Dispatcher.Run();
}

When the main window is closed, I have the closing event call the application shutdown method like this:

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
    Application.Current.Shutdown();
}

This closes all windows that were created within the same thread as the main window, however this is not closing my other windows that I opened with in new threads. How do I make sure that all of my windows close when the main window closes?

Edit: The linked post only partially answered my question. Using the function Environment.Exit(0); worked for closing every window, but it is causing all of my windows to close about 2-3 seconds after clicking the X button, whereas Application.Current.Shutdown(); closes the windows immediately but leaves the other threads open. There is nothing happening on the same thread after Shutdown gets called so I do not need a return statement after it.

PhantomWhiskers
  • 218
  • 1
  • 10
  • This? [How to exit a WPF app programmatically?](http://stackoverflow.com/questions/2820357/how-to-exit-a-wpf-app-programmatically) – Khalil Khalaf Jul 26 '16 at 00:58
  • I tried using `Environment.Exit(0);` and it works, but now it takes the program about 2-3 seconds to close instead of happening immediately like it does with `Application.Current.Shutdown();`. – PhantomWhiskers Jul 26 '16 at 01:04
  • 1
    have the main window keep a collection of all child windows opened and when it is going through its shut down sequence close all child windows. – Nkosi Jul 26 '16 at 01:13
  • That might be what I have to do. Will the new threads running my separate windows be terminated when it's window is closed? – PhantomWhiskers Jul 26 '16 at 01:18
  • Your code works, if you click X on MainWindow, then all windows are closed also. –  Jul 26 '16 at 01:27
  • It doesn't close the windows that are started in a new thread though. If I just instantiate a new window and call it's Show function, it will close those, but when I create a new thread and call the window's Show function in that thread, the window won't be closed when `Application.Current.Shutdown();` is called. – PhantomWhiskers Jul 26 '16 at 01:29
  • Believe it or not, I copy paste your code and it works. All windows are closed. –  Jul 26 '16 at 01:33
  • Weird. On my program, it doesn't close the windows in new threads. They stay open and the process doesn't terminate. – PhantomWhiskers Jul 26 '16 at 01:37
  • FYI : I'm using Win10 with VS2015.3 with .NET 4.5.2 –  Jul 26 '16 at 01:40
  • I am using Win10 with VS2015.3 also, but my .NET version is 4.6.01586. I made a new extremely simple project, and I am getting the same issue. – PhantomWhiskers Jul 26 '16 at 01:54

2 Answers2

3

You can change the ShutdownMode in your project properties to shutdown when your MainWindow is closed. In your "Application.xaml" file change

ShutdownMode="OnLastWindowClose"

to

ShutdownMode="OnMainWindowClose"
Tarrokk
  • 88
  • 4
0

I figured out a way to do it myself without having to call Environment.Exit(0); by instead creating a List of Threads, and then called the thread dispatcher's InvokeShutdown method. Here is the modified code from above:

private List<Thread> threadList = new List<Thread>();

private void NewWindowButton_Click(object sender, RoutedEventArgs e) {
    Thread WindowThread = new Thread(new ThreadStart(NewWindowThread));
    threadList.Add(WindowThread);
    WindowThread.SetApartmentState(ApartmentState.STA);
    WindowThread.IsBackground = true;
    WindowThread.Start();
}

private void NewWindowThread() {
    var NewWindow = new NewWindow();
    NewWindow.Show();
    Dispatcher.Run();
}

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    foreach (Thread thread in threadList)
    {
        Dispatcher.FromThread(thread).InvokeShutdown();
    }
    Application.Current.Shutdown();
}

This causes all windows in separate threads to close when the main window is closed, and it doesn't cause any delay like Environment.Exit(0); did.

PhantomWhiskers
  • 218
  • 1
  • 10