Search code examples
c#windowsformshost

How to properly use the dispose method on a class


I'm working on a database and I need to write the database to file when the database class is destroyed along with every else when the form is closed

This is how I'm currently calling it:

class database: IDisposable
{
    List<databaseEntry> dDatabase;

    public database()
    {
        dDatabase = new List<databaseEntry>;
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
             StreamWriter sw = new StreamWriter(path);

             string toWrite;

             foreach (databaseEntry dE in dDatabase)
             {
             toWrite = dE.rfid.ToString() + " " + dE.currentArea.ToString() + " " + dE.itemName;
             sw.WriteLine(toWrite);
             }

             sw.Close();
             disposed = true;
         }
     }//destructor for database (saves database to file)

     public void Dispose()
     {
          Dispose(true);
          GC.SuppressFinalize(this);
     }
 }

The Dispose method isn't called when I close the windows form that this class is open in.

This is for an assignment and I'm not allowed to use SQL for this.


Solution

  • You do not have control over when the Dispose method is called by the garbage collector. If you want to dispose resources when the form is closed, you should manually call the Dispose method when the form is closed.

    This is achieved by listening to the FormClosed event of the form.

    So you would do something similar to this:

    1. Create this method:

      private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
      {
          if(this.database != null)
              this.database.Dispose(); 
      }
      
    2. Put this line in your form's constructor:

      this.FormClosed += Form1_FormClosed;
      

    Since you're implementing IDisposable, another solution would be to wrap your database object instantiation in a using statement - this would automatically call Dispose once the code in the using statement completes.

    Syntax for your use case is as follows:

    using(database db = new database())
    {
        //use your db object
    } //db is disposed here