在我的Windows 8.1(WinRT)应用中,我使用SQLite v 3.8.9,SQLite-net作为我的数据库,SemaphoreSlim作为我的同步执行器。它通常有效,但有时当我尝试删除表条目时它会在SQLite的C ++代码中崩溃。
(项目名称)中(代码)的第一次机会异常:Microsoft C ++异常:内存位置(位置)的_com_error。
private static SemaphoreSlim _mutex = new SemaphoreSlim(1,5);
public void DeleteItem(Item item)
{
_mutex.Wait();
using (var connection = new SQLiteConnection(Path))
{
connection.Delete(item);
}
_mutex.Release();
}
public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false)
{
...
#if NETFX_CORE
SQLite3.SetDirectory(/*temp directory type*/2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
#endif
...
}
在调用SQLite3.SetDirectory
时发生崩溃。
例外:
消息:
尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
堆栈跟踪:
在SQLite.SQLite3.SetDirectory(UInt32 directoryType,String directoryPath)
在SQLite.SQLiteConnection..ctor(String databasePath,SQLiteOpenFlags openFlags,Boolean storeDateTimeAsTicks)
在SQLite.SQLiteConnection..ctor(String databasePath,Boolean storeDateTimeAsTicks)
我猜这必定是一个线程问题因为它通常有效并且有不规则的崩溃;但是我找不到任何东西。
异常的原因是什么,我该怎么做才能解决?
我不认为它是损坏的内存,可能受到保护,但我相当确定只有一个线程正在访问它
答案 0 :(得分:1)
最后,尽管我确信一次只有一个线程正在访问SQLite数据库,但事实证明我有一些我没想到同时被调用的次要代码;这导致了AccessViolationException
为了确保将来不会出现此问题,我执行了以下操作:
工厂数据库类
public class DataBaseConnection: SQLite.SQLiteConnection
{
private const string _path = "MySQlitePath";
private static SemaphoreSlim _contextMutex = new SemaphoreSlim(1, 5);
private DataBaseConnection() : base(_path)
{
}
public static DataBaseConnection CreateDataBaseConnection()
{
_contextMutex.Wait();
return new DataBaseConnection();
}
private bool disposed = false;
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if(disposing)
{
}
disposed = true;
base.Dispose(disposing);
_contextMutex.Release();
}
}
使用工厂
using (var connection = DataBaseConnection.CreateDataBaseConnection())
{
connection.Delete(item);
}
自从使用此功能后,我再也没见过AccessViolationException
。
如果您使用多个连接(即不同的数据库路径),例如:
您应该始终使用相同的同步机制(在我的情况下为SemaphoreSlim
),以确保在任何给定时间只打开一个 SQLite连接;即使他们正在访问不同的文件。