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

あなたの推測は正しいと確信しています。しかし、何がうまくいかなかったのかを推測するのはかなり困難です (例えば、あなたのconnectionStringwill で定義されているものが、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句が作成したインスタンスを破棄することが保証されます。

また、(最初の) 接続インスタンスを再利用することを検討することもできます。たとえば、一度開くと、アプリケーションのどこでも再利用できます。この場合、スレッドに注意する必要があります(デフォルトでは、変更できます。各接続は、それを作成したスレッドでのみ安全に使用できます)。

再利用するとアプリのパフォーマンスが向上する可能性がありますが、問題が実際に解決されるわけではありません (ただし、問題が隠される可能性があります)。したがって、最初にこれをデバッグすることをお勧めします。

/Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.csMonoDevelop を使用すると、ファイル (MonoTouch インストールに含まれている)の 136 行目にブレークポイントを設定して、実際のnエラー コードを (文字列に変換される前に) 確認できます。

Dispose コードにブレークポイントを設定して、確実に実行されるようにすることもできます (エラーが返されません)。接続の作成と破棄の数は一致する必要があります。そうでない場合は、コール スタックを使用して、誰が閉じずに開いているかを確認します。

于 2012-10-14T15:47:10.053 に答える
1

「using」ブロックを使用することをお勧めします..これにより、すべてが正しく破棄され、接続が既に閉じられているときに接続を閉じていないことが確認されます..

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

}
于 2012-10-14T15:45:16.083 に答える
0

OK - 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 に答える