The correct way to store information in a file when the application terminates

One of my classes collects statistics at runtime, and I want to save these statistics to disk when the application terminates. I never destroy this class inside my program, so I tried to save the logs this way:

~Strategy() { foreach(var item in statisticItems) { log.WriteLine(item.Text); // log is AutoFlush } } 

However, I do not see the logs that I expect to see, nor can I "catch" at the time of the debugger when I called the destructor.

Questions:

  • Why in the debugger I can not catch the moment when the destructor is called? Isn't it necessary to call a destructor for each object when the program ends?
  • What should I use to register my items?
+6
source share
3 answers

A destructor (or finalizer) is not a place to place such code. It is designed to free up unmanaged resources. Destructors are called non-deterministic, so you cannot rely on any of your objects to be valid inside the destructor. And you cannot catch it in the debugger, because it is called in a separate thread, in special circumstances. In short, do not use destructors unless you know what you need.

The ideal way to register for application closure is to simply put the logging code at the end of the Main method. You need to make sure that you catch and write down any exceptions that were thrown, and if so, you can write the end at the end of Main .

There will be several edge cases where you cannot register a shutdown due to errors such as stack overflows. In these cases, you will need to rely on the logs of what happened before the error.

+1
source

Do not rely on destructors. I would recommend using something like this:

 [STAThread] static void Main() { using(new Strategy()) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public class Strategy : IDisposable { public void Dispose() { WriteLogs() } ... } 

This way you are sure that your logs will be recorded.

The static void Main is copied from the default program.cs file, which is created when the Windows forms application is created.

-1
source

This is not a complete answer (for now), but check this:

The programmer does not have control over the call to the destructor because it is determined by the garbage collector. The garbage collector checks for objects that are no longer using an expression. If it considers the object to be destroyed, it calls the destructor (if any) and restores the memory used to store the object. Destructors are also called when the program terminates.

Source: MSDN

If this is a console application, you can try calling Environment.Exit(0); to find out what is going on?

Keep this answer as this is an interesting question. Anyone can edit.

Hi

-1
source

Source: https://habr.com/ru/post/920728/


All Articles