Asynchronous processing and Application.Shutdown ()

4 minute read

Introduction

This article is for * C # WPF.Net Flamework *. In the system that implements asynchronous processing, the record (as of 9/13/2020) when searching for the best practice of termination processing that appropriately discards asynchronous processing is summarized in Personal.

About asynchronous processing

foreground / background thread overview

Managed threads are classified into the following two types.

type Description
foreground thread You can maintain a managed execution environment.
background thread Unable to maintain a managed execution environment. That is, when all foregrounds are stopped, the system will stop all background threads.

This means that when asynchronous processing is executed on the UI thread, the behavior is different when the UI thread is stopped during asynchronous processing execution. The “background thread” ends when the UI thread ends, but the " foreground thread "does not. `

foreground / background thread Judgment method

Next, check which is the specific asynchronous process.
The easiest way to do this is to stop the UI thread while the asynchronous process is actually running, but it’s easiest to refer to the property Thread.IsBackground.
However, if you want to execute asynchronous processing without creating a Thread object, you can check the default value of * Thread.IsBackground * by writing the following in the asynchronous processing.

Console.WriteLine(Thread.CurrentThread.IsBackground);

By the way, the default value when a Thread object is created is * False *, and when executing asynchronous processing with Task.Run (), * Ture * is the default value.

About the end of Application

So far, we have described the precautions regarding the relationship between UI threads and asynchronous threads, but we will touch on the relationship at the end of Application, which is the main subject. To conclude first, when ʻApplication ends, asynchronous threads will end, regardless of the type of managed thread. Let’s take a closer look at the end of Application.
Window.Close()
Basically, the Application is terminated by calling the Close () method in `MainWindow.xaml.cs created by the WPF application template. However, this is not the case if you edit App.xaml or App.xaml.cs.

Strictly speaking, it depends on whether * Application.ShutdownMode * was set to * OnLastWindowClose * when the * Window * instance set to * Application.MainWindow * was * Close () *.
Application.ShutdownMode
If * Application.ShutdownMode * is set to the default value * OnLastWindowClose *, Application will be closed at * Close () * of the Window instance set to * Application.MainWindow *. However, if ʻOnExplicitShutdown is set, Close () = Application will not end. ``

  • Appication may end as a result, but there is a risk that the Application will remain alive.

So in the latter case, you need to explicitly call the Application.Shutdown () method instead of Close (). Application.MainWindow Now let's see how to set up a Window instance in * Application.MainWindow *. There are two ways to set it in * Application.MainWindow *: ʻApp.xaml and ʻApp.xaml.cs. If you created a WPF application from a template, it is described in * StartupUri * of Application in ʻApp.xaml.

App.xaml


<Application x:Class="HelloWorld.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

Next, I will show you how to set the MainWindow in App.xaml.cs.

App.xaml


<Application x:Class="HelloWorld.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="AppStartup">
    <Application.Resources>

    </Application.Resources>
</Application>

App.xaml.cs


public partial class App : Application
{
    void AppStartup(object sender, StartupEventArgs e)
    {
        MainWindow window = new MainWindow();
        window.Show();
    }
}

In this method, a Window instance is created on the Startup event of ʻApp.xaml.cs without directly specifying xaml in * StartupUri * of ʻApp.xaml.
  

As a supplement here, it is not explicitly set in * Application.MainWindow * above. However, the generated MainWindows instance is actually set in * Application.Mainwindow *. This is because the specification is that the instance is automatically set in * Application.MainWindow * when the Windows instance is first created, so the description is as above. Therefore, if you create two Window instances in the same event, note that * Application * will enter the termination process when the first created Window instance is * Close () *, so the subsequent processing will not be executed. please.

App.xaml.cs


public partial class App : Application
{
    void App_Startup(object sender, StartupEventArgs e)
    {
        //When you create a Windows instance, that instance is automatically created
        // Application.Set in MainWindow.
        Window firstWindow = new MainWindow();
        Window secondWindow = new MainWindow();
        
        firstWindow.ShowDialog();
        //No migration process is performed.
        secondWindow.ShowDialog();
    }
}

Summary

From the above, it was concluded that the application that implements asynchronous processing should be implemented with the following in mind.

  • Asynchronous processing is processed by * “background thread” * unless there is a reason.
  • Regardless of the type of managed thread, asynchronous threads can also be terminated by terminating Application.
    • Considering that Application.ShutdownMode * and * Appication.MainWindow * will be edited, basically use * Application.ShutDown () * explicitly instead of * Close () * to perform Application shutdown. To describe.
* Garbage collection will be complicated, so I won't touch it here.

Tags: ,

Updated: