Home > Mobile >  How do I save my data on .txt file, destructor doesn't work?
How do I save my data on .txt file, destructor doesn't work?

Time:12-15

On my last try every adding section it adds 3x data on data.txt

I think that I can do my save on my destructor method but it doesn't work.

data format consists of 3 string expression likes: date soccer team country

This is a section from my DataStructor class

takimlar.Add("1905", "GS", "TR");


internal class Node
        {
            internal T ulke;
            internal T takim;
            internal T tarih;
            internal Node next = null;
            internal Node pre = null;
            internal Node(T tarih, T takim, T ulke)
            { this.tarih = tarih; this.takim = takim; this.ulke = ulke; }
        }
internal IEnumerable<string> GetEnumerator()
        {
            for (Node traveler = first; traveler != null; traveler = traveler.next)
               yield return $"{traveler.tarih},{traveler.takim},{traveler.ulke}";
        }
internal IEnumerable<Node> GetEnumeratorNodeUlke(T ulke)
        {
            for (Node traveler = first; traveler != null; traveler = traveler.next)
                if (traveler.ulke.Equals(ulke))
                    yield return traveler;
        }

How it can be fixed?

using System;
using System.Windows.Forms;
using System.IO;
using System.Linq;
using System.Collections.Generic;

namespace TAKIM_ULKE
{
    internal partial class MainForm : Form
    {
        AdderForm adderForm = new AdderForm();
        static string filePath = @"C:\Users\nevfe\source\repos\TAKIM_ULKE\TAKIM_ULKE\bin\Debug\netcoreapp3.1\data.txt";
        List<string> lines = new List<string>();
        List<string> output = new List<string>();
        
        internal MainForm()
        {
            InitializeComponent();

            lines = File.ReadAllLines(filePath).ToList();
            foreach (string line in lines)
            {
                string[] entries = line.Split(',');
                adderForm.takimlar.Add(entries[0], entries[1], entries[2]);
            }

            foreach (var item in adderForm.takimlar.GetEnumeratorUlke())      //Ülkeleri listele
                ulkeComboBox.Items.Add(item);
        }
        ~MainForm()
        {
            foreach (string item in adderForm.takimlar.GetEnumerator())
                if (!lines.Contains(item))
                    output.Add(item);

            File.WriteAllLines(filePath, output);
        }
     }
}

CodePudding user response:

The problem with the destructor, also known as Finalizer, is that it is called when the object goes out of scope and collected by the garbage collector.

This means that C# works differently compared to some other languages.

The purpose is to clean up and free any resources, normally in the destructor this should be unhandled resources. This means that you should not be executing "business logic" such as writing to files in a destructor.

There is also no guarantee that the destructor will be called at all or when it will be called. Because the GC does not necessarily destroy objects at the exact moment they go out of scope, but waits until it is convenient.

There are several other posts about this which you can read in more detail if you wish, where others have explained this much better than I can!

Why does my destructor never run?

When should I create a destructor?

So then how should you solve this?

Well, reading the posts, you will see that a better solution is to use the IDispose pattern. But this is also really designed to clean-up after you have finished with the object. As you still need to execute business logic, then IMHO this is still not the right place.

So then you should be looking at the Events of the Winform. So if we look at the Winform lifecycle here https://docs.microsoft.com/en-us/dotnet/desktop/winforms/order-of-events-in-windows-forms?view=netframeworkdesktop-4.8

Then we see that we have several options when closing the form / application, so you can select the one which suits you.

I would suggest, if you need to cancel the form closing (e.g. if writing fails), then use Form.Closing. Else use Form.Closed.

CodePudding user response:

Your destructor may not be called at all due to application closing.
Use FormClosing event.

Read more here.

  • Related