C# 为什么SQLite仍然不能以串行模式从多个线程快速写入?

C# 为什么SQLite仍然不能以串行模式从多个线程快速写入?,c#,multithreading,sqlite,locking,entity-framework-core,C#,Multithreading,Sqlite,Locking,Entity Framework Core,我正在尝试使用多线程,使用EF Core 2.2非常快地将记录写入SQLite(1000行,延迟约20毫秒)。我得到这个错误: System.InvalidOperationException:'在此服务器上启动了第二个操作 上一个操作完成之前的上下文。这通常是由于 但是,不同的线程使用相同的DbContext实例 实例成员不能保证是线程安全的。这也可能 可能是由客户端上正在计算的嵌套查询引起的,如果 案例将重写查询,避免嵌套调用。” 我可以使用WAL(写前日志记录),它工作得更好,但仍然会导致

我正在尝试使用多线程,使用EF Core 2.2非常快地将记录写入SQLite(1000行,延迟约20毫秒)。我得到这个错误:

System.InvalidOperationException:'在此服务器上启动了第二个操作 上一个操作完成之前的上下文。这通常是由于 但是,不同的线程使用相同的DbContext实例 实例成员不能保证是线程安全的。这也可能 可能是由客户端上正在计算的嵌套查询引起的,如果 案例将重写查询,避免嵌套调用。”

我可以使用
WAL(写前日志记录)
,它工作得更好,但仍然会导致问题,如果我对WAL使用手动锁定,那么它就可以工作,但我不喜欢使用单独的文件带来的不便,如果发生崩溃,这些文件不会保存到主数据库。使用一个没有墙壁的简单锁也可以,但是一次最多可以冻结几秒钟

使用此配置编译SQLite程序集时,为什么会发生此错误:

COMPILER=msvc-1700
DEFAULT_FOREIGN_KEYS
ENABLE_COLUMN_METADATA
ENABLE_FTS3_PARENTHESIS
ENABLE_FTS4
ENABLE_FTS5
ENABLE_JSON1
ENABLE_RTREE
THREADSAFE=1
THREADSAFE=1
表示序列化,当多个线程试图使用同一个DbContext写入数据库时,应根据序列化防止出现问题

SQLITE_THREADSAFE=1)SQLITE库本身将序列化访问 到数据库连接和准备好的语句,以便 应用程序可以自由使用相同的数据库连接或相同的 同时在不同线程中准备语句


我想了解为什么会发生这种情况。

从多线程执行写操作的唯一明智的方法是使用多线程模式,并让每个线程使用自己的数据库专用句柄。正如您所看到的,尝试在多个线程之间共享一个句柄只会有太多的陷阱和发生奇怪交互的机会。从您的错误判断,这是一个EF问题,而不是SQLite问题。您的pragmas看起来是正确的,SQLite是线程安全的,但EF Core不是。请参阅,从多线程执行写操作的唯一合理方法是使用多线程模式,并让每个线程使用自己的数据库专用句柄。正如您所看到的,尝试在多个线程之间共享一个句柄只会有太多的陷阱和发生奇怪交互的机会。从您的错误判断,这是一个EF问题,而不是SQLite问题。您的pragmas看起来是正确的,SQLite是线程安全的,但EF Core不是。看见