MonoTouch SQLite插入错误 - 无法打开数据库文件

时间:2011-08-24 15:51:53

标签: c# insert sqlite xamarin.ios out-of-memory

我正在使用MonoTouch并遇到了一些SQLite问题:

在使用Mac上的iPad模拟器进入Sqlite数据库的几百次,有时数千次插入后,出现以下错误:

<<

    Mono.Data.Sqlite.SqliteException: Unable to open the database file
      at Mono.Data.Sqlite.SQLite3.Reset (Mono.Data.Sqlite.SqliteStatement stmt)
    [0x0008a] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs:226 
      at Mono.Data.Sqlite.SQLite3.Step (Mono.Data.Sqlite.SqliteStatement stmt)
    [0x00046] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs:168 
      at Mono.Data.Sqlite.SqliteDataReader.NextResult () [0x00129] in
    /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataReader.cs:908 
      at Mono.Data.Sqlite.SqliteDataReader..ctor (Mono.Data.Sqlite.SqliteCommand
    cmd, CommandBehavior behave) [0x00051] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataReader.cs:89 
      at (wrapper remoting-invoke-with-check) Mono.Data.Sqlite.SqliteDataReader:.ctor (Mono.Data.Sqlite.SqliteCommand,System.Data.CommandBehavior)
      at Mono.Data.Sqlite.SqliteCommand.ExecuteReader (CommandBehavior behavior) [0x00006] in
    /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:539 
      at Mono.Data.Sqlite.SqliteCommand.ExecuteNonQuery () [0x00000] in
    /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:568 
      at iDispatch.DevVehicle.Insert () [0x0003f] in
    /Users/Projects/iDispatch/iDispatch/DevVehicleDAL.cs:240 

>>

这通常是内部堆栈跟踪:

<<

    Stacktrace:

      at (wrapper managed-to-native) Mono.Data.Sqlite.UnsafeNativeMethods.sqlite3_prepare (intptr,intptr,int,intptr&,intptr&) <IL 0x0002a, 0xffffffff>
      at Mono.Data.Sqlite.SQLite3.Prepare (Mono.Data.Sqlite.SqliteConnection,string,Mono.Data.Sqlite.SqliteStatement,uint,string&) [0x00044] in
    /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs:258
      at Mono.Data.Sqlite.SqliteCommand.BuildNextCommand () [0x00019] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:230
      at Mono.Data.Sqlite.SqliteCommand.GetStatement (int) [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:264
      at (wrapper remoting-invoke-with-check) Mono.Data.Sqlite.SqliteCommand.GetStatement (int) <IL 0x00039, 0xffffffff>
      at Mono.Data.Sqlite.SqliteDataReader.NextResult () [0x000cc] in
    /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataReader.cs:891
      at Mono.Data.Sqlite.SqliteDataReader..ctor
    (Mono.Data.Sqlite.SqliteCommand,System.Data.CommandBehavior) [0x00051] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataReader.cs:89
      at (wrapper remoting-invoke-with-check) Mono.Data.Sqlite.SqliteDataReader..ctor (Mono.Data.Sqlite.SqliteCommand,System.Data.CommandBehavior) <IL 0x00021, 0xffffffff>
      at Mono.Data.Sqlite.SqliteCommand.ExecuteReader (System.Data.CommandBehavior)
    [0x00006] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:539
      at Mono.Data.Sqlite.SqliteCommand.ExecuteNonQuery () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs:568
      at iDispatch.DevVehicle.Insert () [0x0003f] in /Users/Projects/iDispatch/iDispatch/DevVehicleDAL.cs:240
      at iDispatch.ThreadSQL.DoWorkSQL () [0x0038a] in /Users/Projects/iDispatch/iDispatch/ThreadSQL.cs:140
      at System.Threading.Thread.StartUnsafe () [0x00016] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading/Thread.cs:684
      at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) <IL 0x0004e, 0xffffffff>

Native stacktrace:

    0   iDispatch                           0x000d0db5 mono_handle_native_sigsegv + 343
    1   iDispatch                           0x0000f80c mono_sigsegv_signal_handler + 322
    2   libSystem.B.dylib                   0x9833705b _sigtramp + 43
    3   ???                                 0xffffffff 0x0 + 4294967295
    4   libsqlite3.dylib                    0x03645dc1 sqlite3DbStrNDup + 33
    5   libsqlite3.dylib                    0x03645e07 sqlite3NameFromToken + 23
    6   libsqlite3.dylib                    0x036486dc sqlite3IdListAppend + 92
    7   libsqlite3.dylib                    0x03682720 sqlite3Parser + 11904
    8   libsqlite3.dylib                    0x03684536 sqlite3RunParser + 310
    9   libsqlite3.dylib                    0x03684b34 sqlite3Prepare + 276
    10  libsqlite3.dylib                    0x03684fa7 sqlite3LockAndPrepare + 151
    11  ???                                 0x10c309ff 0x0 + 281217535
    12  ???                                 0x10c2fd1c 0x0 + 281214236
    13  ???                                 0x10c2f857 0x0 + 281213015
    14  ???                                 0x10c2f58a 0x0 + 281212298
    15  ???                                 0x10c2f50a 0x0 + 281212170
    16  ???                                 0x10c2eeea 0x0 + 281210602
    17  ???                                 0x10c2ea3c 0x0 + 281209404
    18  ???                                 0x10c2e8d6 0x0 + 281209046
    19  ???                                 0x10c2cc9e 0x0 + 281201822
    20  ???                                 0x10c2cb30 0x0 + 281201456
    21  ???                                 0x10fde444 0x0 + 285074500
    22  ???                                 0x10bb6786 0x0 + 280717190
    23  ???                                 0x106f2cba 0x0 + 275721402
    24  ???                                 0x077cfbf0 0x0 + 125631472
    25  iDispatch                           0x0000f5c7 mono_jit_runtime_invoke + 1332
    26  iDispatch                           0x001ed281 mono_runtime_invoke + 137
    27  iDispatch                           0x001ee8d1 mono_runtime_delegate_invoke + 111
    28  iDispatch                           0x00229c74 start_wrapper_internal + 692
    29  iDispatch                           0x00229cc2 start_wrapper + 17
    30  iDispatch                           0x00266b99 thread_start_routine + 191
    31  iDispatch                           0x002974f1 GC_start_routine + 107
    32  libSystem.B.dylib                   0x982fe259 _pthread_start + 345
    33  libSystem.B.dylib                   0x982fe0de thread_start + 34
* Assertion at ../../../../mono/mini/mini-exceptions.c:2188, condition `res != -1' not met
>>

仅供参考: iDispatch 是我的计划名称。

现在,虽然我使用多种方法插入多个表,但问题随机出现在任何和所有方法中。通常,insert方法看起来像这样:

<<

    public void BulkInsert(StandardEquipmentCollection sec)
    {
        try
        {
            Connection.Open();

            SQLiteCommand cmd = Connection.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText =
                "INSERT INTO StandardEquipment (" + "Category, Description, VehicleID" +
                ") VALUES (" + "@Category, @Description, @VehicleID)";
            foreach (StandardEquipment se in sec)
            {
                cmd.Parameters.AddWithValue("@Category", se.Category);
                cmd.Parameters.AddWithValue("@Description", se.Description);
                cmd.Parameters.AddWithValue("@VehicleID", se.VehicleID);
                cmd.ExecuteNonQuery();
            }

            Connection.Close();
        }
        catch (Exception ex)
        {
            threadSQL.AddOutQ("Error: StandardEquipment BulkInsert - " + ex);
        }
    }

>>

在插入100个(有时是1000个)记录后出现问题。

使插入到表中的那些看起来很好(我使用Navicat Lite),并且它出错的那些看起来也很好(即从调试器我可以看到所有数据都是正确的,格式也是如此)

我在Windows上运行完全相同的代码(ADO.NET 2.0 Data Provider for SQLite),Mono for Windows和Mono在MacBook Pro上运行......仅限于 MonoTouch(版本2.4.2;版本号:20402005; Git版本: b7eeb779e1134c204f22d9fd5b6ebec4d758f60d;建设日期:2011-04-22 22:48:43 + 0000) 看到这个错误。

非常感谢任何帮助!

BTW:在网上搜索解决方案后,我添加了以下'Persist Journal'命令,但它没有效果:

<<
SqliteConnectionStringBuilder connectionStringBuilder = new SqliteConnectionStringBuilder ();
connectionStringBuilder.JournalMode = SQLiteJournalModeEnum.Persist;
connectionStringBuilder.DataSource = dbPath;
SqliteConnection Connection = new SqliteConnection(connectionStringBuilder.ConnectionString);
>>

谢谢!

1 个答案:

答案 0 :(得分:1)

根据您的描述,这看起来像是内存不足的情况。请记住,与台式计算机相比,iOS设备的内存不多。您可能会耗尽内存太快而在非托管代码中崩溃。例如如果没有附加调试器,则仅针对SEGSIGV(来自本机代码)命中以下行:

* Assertion at ../../../../mono/mini/mini-exceptions.c:2188, condition `res != -1' not met

要解决此问题,请尝试使用使用或调用 Dispose 来处理您的对象(所有实现IDisposable的对象)和/或在可能的情况下回收它们。

看一看 How can I recycle my SqliteCommand to speed up this Sqlite bulk insert (iOS)?为后者。

相关问题