我正在研究一个多线程的wpf应用程序,我得到了#34; AccessViolationException"说试图读取或写入受保护的内存。这通常表明其他内存已损坏。 在我的ConnectionOpen()中。 我的代码如下。
public class DatabaseServices
{
static SQLiteConnection connection;
static object conLock = new object();
static object conCloseLock = new object();
public static SQLiteDataReader ConnectionOpen(string Query)
{
lock (conLock)
{
if (connection != null && connection.State != System.Data.ConnectionState.Open)
{
connection = new SQLiteConnection("Data Source=Database/abc.sqlite");
connection.Open();
}
else if (connection == null)
{
connection = new SQLiteConnection("Data Source=Database/abc.sqlite");
connection.Open();
}
SQLiteCommand mycommand = new SQLiteCommand(Query, connection);
SQLiteDataReader sqlite_datareader = mycommand.ExecuteReader();
return sqlite_datareader;
}
}
public static void ConnectionClose()
{
lock (conCloseLock)
{
connection.Close();
}
}
}
我已经使用了锁以及线程安全代码,但它不能正常工作。为什么?
答案 0 :(得分:1)
SQLiteConnection
不是线程安全的。与所有其他数据库连接一样,您应该为每个线程打开一个。您的代码有一些部分即使它 线程安全也无法工作,这一事实也无济于事。例如,任何人都可以关闭连接,而其他人只是查询它。
保持完善的模式。不要跨线程使用数据库连接。不要编写自己的连接缓存。打开一个连接,做你的工作,然后关闭它。如果你肯定需要连接缓存,请查看数据库的文档并了解内置机制的工作原理。
答案 1 :(得分:1)
SQLite不支持多活动结果集(MARS)
因此,您不能为同一连接提供多个DataReader。
连接(并删除锁定)后,您分发DataReader。我假设客户端代码调用此ConnectionOpen方法两次导致(或者更确切地说是尝试)重用相同的连接。
为每个DataReader创建一个连接。
使用连接池时:
Data Source=c:\mydb.db;Version=3;Pooling=True;Max Pool Size=100;
当正确关闭时,连接将被回收/合并。这将减少创建和打开连接的开销。