C# sqlite中的多线程

ejk8hzay  于 2023-04-21  发布在  SQLite
关注(0)|答案(3)|浏览(345)

我正在构建一个C# wpf应用程序,并使用一个Sqlite数据库。假设我有25个辅助线程等待执行插入操作,主线程同时尝试执行选择操作。
我可能是错的,但是主线程将不得不等待一段时间。我如何确保数据库在我的日志文件中被锁定?我如何确保主线程具有最高优先级,以便我的UI不会被阻塞?
我正在使用DBContext对象来执行数据库操作。

wa7juj8i

wa7juj8i1#

巧妙地使用ReaderWriterLockSlim肯定会帮助您提高性能。

private ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim();

    private DataTable RunSelectSQL(string Sql)
    {
        DataTable selectDataTable = null;
        try
        {
            _readerWriterLock.EnterReadLock();                
            //Function to acess your database and return the selected results
        }
        finally
        {
            _readerWriterLock.ExitReadLock();
        }
        return selectDataTable;
    }

    private DataTable RunInsertSQL(string Sql)
    {
        DataTable selectDataTable = null;
        bool isbreaked = false;
        try
        {
            _readerWriterLock.EnterWriteLock();
            if (_readerWriterLock.WaitingReadCount > 0)
            {
                isbreaked = true;
            }
            else
            {
                //Function to insert data in your database
            }
        }
        finally
        {
            _readerWriterLock.ExitWriteLock();
        }

        if (isbreaked)
        {
            Thread.Sleep(10);
            return RunInsertSQL(Sql);
        }
        return selectDataTable;
    }

尝试一下,它会提高你的响应能力,你有Select查询要激发,它的优先级高于Insert SQL。
请注意,如果一些插入已经在运行,那么Select至少会等待插入完成。这段代码将始终优先考虑SELECT,而不是INSERT

还有一点,千万不要像从数据库中选择那样,在主线程上执行长时间持续操作,而是在后台执行操作,然后通过主线程将最新的结果反映到UI上,这样可以保证您的UI永远不会冻结。
EDIT如果有连续的SELECT查询被触发而没有任何间隙,则可能存在所有INSERT都在等待的饥饿情况。

但我相信在你的情况下,这不会发生,因为UI不会总是刷新,以获得最新的变化,如此频繁,没有任何时间片之间。

r55awzrz

r55awzrz2#

你在什么模式下运行数据库?
SQLite支持三种不同的线程模式:
1.单线程。在这种模式下,所有互斥锁都被禁用,SQLite一次在多个线程中使用是不安全的。
1.多线程。在这种模式下,SQLite可以安全地由多个线程使用,前提是没有单个数据库连接同时在两个或多个线程中使用。
1.序列化。在序列化模式下,SQLite可以安全地由多个线程使用,没有任何限制。

默认为序列化模式。

http://www.sqlite.org/threadsafe.html
看起来多线程是你想要的。序列化数据库访问是 * 慢 *。

mwecs4sa

mwecs4sa3#

A在我的多线程缓存子系统中有完全相同的问题,看起来像是'System.Data.SQLite'库的问题
添加此(与reflector一起找到)
“...;Version=3;return True;最大池大小=100;”
连接字符串解决了这个问题。

相关问题