【问题标题】:SQLiteConnection DisposedObjectSQLiteConnection DisposedObject
【发布时间】:2012-10-18 17:36:51
【问题描述】:
class SQLiteDatabase
    {
        String dbConnection;
        static SQLiteConnection cnn;
        static int connections = 0;
        /// <summary>
        ///     Default Constructor for SQLiteDatabase Class.
        /// </summary>
        public SQLiteDatabase()
        {
            dbConnection = "Data Source=SQLiteOphthaMetrics.db;foreign keys=true;";
            if (connections == 0)
            {
                cnn = new SQLiteConnection(dbConnection);
                cnn.Open();
                this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS patients ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, birthday TEXT, gender TEXT, iriscolor INTEGER);");
                this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS images ( nameRed TEXT NOT NULL PRIMARY KEY, checksumRed TEXT NOT NULL, "
                    + "nameGreen TEXT NOT NULL, checksumGreen TEXT NOT NULL, state INTEGER, cvalue REAL, sharpness REAL, deviation REAL, area REAL, redExposure REAL, "
                    + "redGain REAL, greenExposure REAL, greenGain REAL, zfocus INTEGER, flipped INTEGER, patientID INTEGER, FOREIGN KEY (patientID) REFERENCES patients(id));");
            }
            connections++;
        }

        ~SQLiteDatabase()
        {
            connections--;
            if (connections == 0)
            {
                cnn.Close();
                cnn.Dispose();
            }
        }
    }

此代码引发 DisposedObjectException

System.ObjectDisposedException was unhandled
  Message=Auf das verworfene Objekt kann nicht zugegriffen werden.
Objektname: "SQLiteConnection".
  Source=System.Data.SQLite
  ObjectName=SQLiteConnection
  StackTrace:
       bei System.Data.SQLite.SQLiteConnection.CheckDisposed()
       bei System.Data.SQLite.SQLiteConnection.Close()
       bei EyeScanner.SQLiteDatabase.Finalize()
  InnerException: 

我目前只在代码中调用 SQLiteDatabase 一次,因此在析构函数中连接数 = 1,但我不明白为什么它会在类析构函数完成之前释放对象。

【问题讨论】:

    标签: c# sqlite exception


    【解决方案1】:

    我相信您正在尝试在类实例准备好释放后释放连接。如果您在 SQLiteConnection 中使用using 语句会更好。 SQLiteConnection 类实现了 IDisposable,您将能够执行以下操作:

    using(cnn = new SQLiteConnection(dbConnection))
    {
         cnn.Open();
         this.ExecuteNonQuery("...your query");
    }
    

    这将充当try/finally 块,即使发生异常,连接也会在using 块之后关闭并释放。

    对于数据库连接,最好的做法是越晚打开越早关闭。

    【讨论】:

    • 但是 cnn.Open() 实际上需要相当多的时间来执行。是否真的打算在 .Close() 上尽可能频繁地使用它?大约需要半秒钟,如果我每次阅读有点臭的数据库时都需要这样做......
    • 好的,更正一下,只有第一个 Open() 需要这么长时间,每个后续都很快。会这样做的,我现在没有更多的例外。
    • 还可以考虑在类上实现IDisposable接口,并在Dispose方法中释放资源,而不是使用析构函数
    • 好的,会这样做。我习惯了C++编程,而C#只用于GUI,但它需要数据库访问,所以我有点迷路了;)
    猜你喜欢
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多