如何在类上正确使用dispose方法

时间:2015-01-20 12:59:34

标签: c# windowsformshost

我正在处理数据库,当表单被关闭时,我需要将数据库写入文件,以及表单关闭时的其他数据库

这就是我目前称之为:

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);
     }
 }

关闭此类打开的窗体时,不会调用Dispose方法。

这是一项任务,我不允许使用SQL。

2 个答案:

答案 0 :(得分:5)

您无法控制垃圾收集器何时调用Dispose方法。如果要在表单关闭时处理资源,则应在表单关闭时手动调用Dispose方法。

这是通过收听表单的FormClosed事件来实现的。

所以你会做类似的事情:

  1. 创建此方法:

    private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
    {
        if(this.database != null)
            this.database.Dispose(); 
    }
    
  2. 将此行放在表单的构造函数中:

    this.FormClosed += Form1_FormClosed;
    
  3. 由于您正在实现IDisposable,另一种解决方案是将数据库对象实例化包装在using语句中 - 这将在{{1}中的代码后自动调用Dispose语句完成。

    您的用例语法如下:

    using

答案 1 :(得分:3)

编辑:

Matthew Watson的评论让我意识到我的答案已经过度简化,可能令人困惑(感谢Matthew的评论)。这是(大部分)真实的故事:

所有对象都有构造函数和析构函数。如果未指定这些,则使用默认构造函数和析构函数。

构造

ClassName()

析构函数:

~ClassName()

使用new关键字时会调用构造函数。一旦不再引用对象的特定实例,就可以调用析构函数 。注意我说可以被称为,而不是被称为。这意味着该对象有资格进行垃圾收集,并且可以在车库收集器运行时释放。我不会在这里详细介绍,但只是知道车库收集器并不总是出于性能原因收集所有无法访问的对象。这是您希望IDisposable界面的主要原因之一。当您知道不再使用资源而不是等待GC清理资源时,您可以立即清理资源。使用流或数据库连接时,最好实现IDisposable接口。

这就是说这里是更新的答案(用析构函数引用替换以前的&#34;默认的Dispose()&#34;引用)。

由于这是一项任务,我本不会给你答案,但我会让你接近。当database对象的实例不再可达时,析构函数(~database)通常由车库收集器调用。通过实现IDisposable接口,您可以选择允许车库收集器处理对象。你在告诉车库收藏家&#34;我知道何时以及如何释放这些资源&#34;与不再引用对象时释放这些资源。但这只适用于调用Dispose方法的情况;更具体地说:

Dispose(true);
GC.SuppressFinalize(this);

这意味着&#34; Garage收集器,不要调用析构函数(~database())方法,我已经处理了它&#34;。

在此方法中应该执行的操作是关闭已打开的任何流(StreamWriter)。

用法:IDisposable接口在C#using语句中有一个很好的构造。这实际上是try catch块,其中在finally块中调用Dispose方法。 StreamWriter还实现了IDisposable,因此您应该考虑在using类中实现database语句。例如:

using(StreamWriter writer = new StreamWriter()){
    //do stuff with writer here
}

这是您应该在表单中用于数据库类的模式。我会让你弄明白如何编写代码。

相关问题