由于多个线程连接到db时,wpf中的AccessViolation异常

时间:2014-08-28 05:38:30

标签: wpf multithreading

我正在研究一个多线程的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();
        }
    }

}

我已经使用了锁以及线程安全代码,但它不能正常工作。为什么?

2 个答案:

答案 0 :(得分:1)

SQLiteConnection不是线程安全的。与所有其他数据库连接一样,您应该为每个线程打开一个。您的代码有一些部分即使它 线程安全也无法工作,这一事实也无济于事。例如,任何人都可以关闭连接,而其他人只是查询它。

保持完善的模式。不要跨线程使用数据库连接。不要编写自己的连接缓存。打开一个连接,做你的工作,然后关闭它。如果你肯定需要连接缓存,请查看数据库的文档并了解内置机制的工作原理。

答案 1 :(得分:1)

SQLite不支持多活动结果集(MARS)

因此,您不能为同一连接提供多个DataReader。

连接(并删除锁定)后,您分发DataReader。我假设客户端代码调用此ConnectionOpen方法两次导致(或者更确切地说是尝试)重用相同的连接。

为每个DataReader创建一个连接。

使用连接池时:

Data Source=c:\mydb.db;Version=3;Pooling=True;Max Pool Size=100;
当正确关闭时,

连接将被回收/合并。这将减少创建和打开连接的开销。