2

我在从 MonoTouch 读取我的 SQLite 数据库中的数据时遇到困难。

对于前几个屏幕,我可以毫无困难地读写,然后突然之间我无法与错误建立任何进一步的联系:

Mono.Data.Sqlite.SqliteException: Unable to open the database file   
at Mono.Data.Sqlite.SQLite3.Open (System.String strFilename, SQLiteOpenFlagsEnum flags, Int32 maxPoolSize, Boolean usePool) [0x0007e] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs:136    
at Mono.Data.Sqlite.SqliteConnection.Open () [0x002aa] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs:888 

我确保每次使用它时都会处理并关闭每个连接,但我仍然遇到这个问题。例如:

var mySqlConn = new SqliteConnection(GlobalVars.connectionString);
mySqlConn.Open();
SqliteCommand mySqlCommand = new SqliteCommand(SQL, mySqlConn);
mySqlCommand.ExecuteNonQuery();
mySqlConn.Close();
mySqlCommand.Dispose();
mySqlConn.Dispose();

我猜我没有正确关闭连接。任何帮助将不胜感激。

4

3 回答 3

2

我很确定你猜对了。然而,很难猜测出了什么问题(例如,您定义的connectionString内容将影响 Sqlite 的初始化方式和工作方式)。

从您的示例中,您似乎正在SqliteConnection正确处理,但事情仍然可能出错。例如,如果某些代码抛出异常(并且您在某处捕获它们),则该Dispose调用可能永远不会被调用。执行以下操作会更安全:

using (var mySqlConn = new SqliteConnection(GlobalVars.connectionString) {
    mySqlConn.Open();
    using (SqliteCommand mySqlCommand = new SqliteCommand(SQL, mySqlConn)) {
        mySqlCommand.ExecuteNonQuery();
        // work with the data
    }
    mySqlConn.Close();
}

这将确保自动finally 子句将处理您创建的实例。

此外,您可能需要考虑重用您的(第一个)连接实例,例如打开一次并在应用程序的任何地方重用它。OTOH,在这种情况下您需要注意线程(默认情况下,您可以更改它,每个连接只能在创建它的线程上安全使用)。

重用可以帮助您的应用程序性能,但它也不能真正解决您的问题(但它可能会隐藏它)。所以我建议你先调试一下:

/Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs使用 MonoDevelop,您可以在文件(包含在您的 MonoTouch 安装中)的第 136 行设置断点,以查看实际的n错误代码(在它被转换为字符串之前)。

您还可以在 dispose 代码上设置断点以确保它被执行(并且不返回错误)。连接创建和处置的数量应该匹配。如果没有,则使用调用堆栈查看谁在打开而不关闭。

于 2012-10-14T15:47:10.053 回答
1

我建议使用“使用”块..这将确保所有内容都正确处理,并且当它已经关闭时您不会关闭连接..

using (SqliteConnection  conn = new SqliteConnection(GlobalVars.connectionString)) 
{
            conn.Open ();
            SqliteCommand command = new SqliteCommand (conn);
                             .............

}
于 2012-10-14T15:45:16.083 回答
0

好的 - 我现在通过将 close 和 dispose 移动到“finally”来让它工作。

var mySqlConn = new SqliteConnection (GlobalVars.connectionString);

mySqlConn.Open ();

try {

// CODE HERE

} finally {

    mySqlConn.Close();
    mySqlConn.Dispose();

}
于 2012-10-14T15:45:36.023 回答