Thoughts on single case application in C# host computer


I. Introduction

I previously wrote an article about singletons - Implementation of the singleton pattern in C# , which talked about what singletons are and common code implementations in C#. The content of that article was theoretical and not practical.

Recently I was using WPF to write a host computer, and found that when I used singletons in actual development, I didn’t care about its underlying implementation, and I rarely saw singleton class code like this:

using System;

public sealed class Singleton
{
    
    
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {
    
    }

   public static Singleton Instance
   {
    
    
      get 
      {
    
    
         if (instance == null) 
         {
    
    
            lock (syncRoot) 
            {
    
    
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

Instead, you often create a service container (ServiceProvider), then add the class you want to implement a singleton into in singleton mode, and make the service container public (usually in the App class) so that the entire program code can access it. , when you want to use the singleton, just take it out of the container:

public IServiceProvider Services {
    
     get; }

private static IServiceProvider ConfigureServices()
{
    
    
    var services = new ServiceCollection();
    services.AddSingleton<Class>();
	...
    return services.BuildServiceProvider();
}

If you haven't used this container method before, you may find it troublesome; but once you accept this method, you will find that it becomes a routine. Almost any application can do this (this approach to service containers is itself a design pattern IOC).

These contents are not what this article is going to talk about. This article mainly wants to talk about the application of singletons in host computer programs and how to use singletons in a scenario.


2. PC single case application scenario

2.1 Host computer

Let me first mention the host computer.
The host computer is usually not a huge program. It is mainly used for:

  • Provides an interface that is user-friendly;
  • Communicate with the lower computer to process the collected data and present it on the interface;
  • Store some data in the database for reports, queries, and statistical analysis;
  • Connect with higher-level systems (MES, ERP, etc.);
  • It may also be combined with some professional technologies (such as vision, document processing, etc.) to assist production.

Such a small program for specialized equipment involves a wide range of technologies.

2.2 Singleton and its applications

The purpose of a singleton is to ensure that a class has only one instance in the program and to provide a global access point to access it.
Obviously, the design of a singleton allows a class to have only one instance, and it should be easy to access from the outside world, so as to facilitate the control of the instance and save system resources.

Therefore, its application scenarios are usually:

  • There are cases of frequent instantiation (that is, frequent new) and then destruction;
  • Creating objects takes too much time or consumes too many resources;
  • Objects that frequently access IO resources, such as database connection pools or files.

I believe that many people use singletons for the first time not because of performance issues, but just because they want something similar to a global variable in C language. They hope that an instance of a class can be accessed by code on different pages. This is actually the feature of providing a global access point mentioned in the singleton.

Here is an application that everyone is very familiar with - the Task Manager on Windows. ctrl + shift + esc opens, and no matter how many times you press it, only one task manager will appear. In other words, in the Windows system, the Task Manager is the only one.

So why is it designed this way? What would happen if it were not designed this way?

  1. If multiple Task Manager windows pop up and the contents displayed in these windows are exactly the same, all the opened objects will be duplicates, which will cause a waste of system resources and memory loss. In actual use, there is no need for multiple windows presenting the same content.
  2. It's even worse if multiple Task Manager windows pop up with inconsistent content. This means that there are multiple states of application usage, processes, services and other information at a certain moment, so which one is real? Obviously this is even more undesirable.

It can be seen that it is very important to ensure that there is only one task manager in the system.

2.3 Application in host computer

In the development of the host computer, similar situations will often be encountered. Here are a few common examples:

2.3.1 User login information

The host computer sometimes requires permission functions, and some page functions require specific permissions to operate.
That is to say, the user information obtained on different pages is consistent. To achieve this requirement, user information must be globally unique. Often when a user logs in, user information containing various permissions is loaded into a singleton.

2.3.2 Configuration file

Host computer programs often require some parameter configuration files, such as those related to equipment and user habits. If you don't use a singleton, you have to create a new object every time and re-read the configuration file, which greatly affects performance. If you use a singleton, you only need to read it once at the beginning.

2.3.3 Data connection pool

Why pooling?
Because creating a new connection is time-consuming, if a new connection is created every time a new task comes, it will seriously affect performance. Therefore, the general approach is to maintain a connection pool in an application, so that when a task comes, if there is an idle connection, it can be used directly, eliminating the cost of initialization.

Notice:
The singleton mentioned here is to make a singleton for the pool, instead of making a singleton for a single database connection.
It is wrong to seal a database connection object in a singleton object. If you make a singleton for a single database connection, then when multiple parties request connections, you can only use one database connection. Isn't that a terrible death?

2.4 Thoughts on an application scenario

In addition to the above general uses, I also tried to use singletons for the need to retain state when switching pages.
The specific scenario is this. There are multiple pages in a host computer in MVVM mode. I hope that after switching pages and then switching back to the original page (the page is the Page, which can be regarded as a View), the displayed content will still be the same as before. The content of the page can be understood as the properties, commands, etc. in the ViewModel.

To meet this requirement, singletons can be used in many ways.

  1. Singleton some key objects in ViewModel (usually the aggregated Model in ViewModel);
  2. Singleton the ViewModel so that there is only one ViewModel in the program;
  3. Singleton the entire View.

Way 1

If the key objects in the ViewModel are singletoned, the ViewModel will be re-created when switching back to the original page, and these singleton objects will be loaded into it.

Way 2

If you singleton the entire ViewModel, you only need to bind the View's DataContext to the singleton ViewModel.

Way 3

If the entire View is singletoned, you only need to navigate to the target singleton View to switch pages.

So the question is, which way is better?
There is obviously no answer to this kind of question, it depends on more specific scenarios.
You can even aggregate several subpages in the homepage class without using a singleton, and then just click to navigate to the subpages.

Now back to the case of using singletons,
if there are many models aggregated in your viewmodel, and the models may be used on other pages, then obviously these models should be singletoned.

If there are many independent status items in your viewmodel, only the status of the page is recorded, which has almost nothing to do with the model. It is also reasonable to make the entire ViewModel singleton.

If there are some linked objects in your View, such as Canvas, and you draw some pictures on the Canvas, the Canvas belongs to the View. It is also reasonable to make View a singleton.

There is no clear answer as to which method will be used in the end. At present, we can only choose a seemingly reasonable method based on the actual situation and test it through practice.


3. Summary

Singleton is a very basic design pattern. Remember it is forEnsure that a class has only one instance in the program and provide a global access point to itThat’s it.

Common application scenarios, user status, configuration files, database connection pools, etc.
It can also be used when the same model is used on multiple pages. There is no need to worry too much about the use of some scenes, as long as the effect can be achieved.

Guess you like

Origin blog.csdn.net/BadAyase/article/details/132523500
Recommended