多线程读取SQLite数据准确率下降且报InvalidOperationException如何解决
问题根因
你的核心问题是类成员变量m_dbConnLocal被多线程共享导致竞态条件:
所有线程调用DownloadListSiteFromDB时都会修改同一个全局的m_dbConnLocal变量指向,比如线程1刚把它赋值为ID25的连接,线程2立刻将它改写为ID27的连接,后续线程1执行Open、查询等操作时实际操作的是被篡改后的连接,自然会出现连接状态异常、数据读取错误的问题。
解决方案
首先明确:改用Dictionary<int, DbConnection>存储连接是合理的,但这只是优化代码结构的手段,核心要解决的是不能用共享成员变量传递当前操作的连接,必须用方法内部的局部变量存储对应连接,彻底切断多线程修改共享变量的路径。
完整修改步骤如下:
- 删除全局共享的
m_dbConnLocal成员变量,改用Dictionary<int, SQLiteConnection>存储预创建的所有连接,替代冗长的if-else判断,初始化示例:
// 类初始化阶段构造连接字典,替代原来的单个连接变量定义 private readonly Dictionary<int, SQLiteConnection> _d10ConnDict = new Dictionary<int, SQLiteConnection> { {1, new SQLiteConnection("Data Source=\\\\sklplfs03\\D10Devprogs\\D10_Monitor\\D10_1.db;version=3;new=False;Timeout=30000;datetimeformat=CurrentCulture")}, {3, new SQLiteConnection("Data Source=\\\\sklplfs03\\D10Devprogs\\D10_Monitor\\D10_3.db;version=3;new=False;Timeout=30000;datetimeformat=CurrentCulture")}, // 其余D10ID对应的连接按上述格式依次添加即可 };
- 调整
DownloadListSiteFromDB的连接获取逻辑,直接从字典取连接赋值给局部变量,完全不涉及共享变量修改:
public bool DownloadListSiteFromDB(List<StructB> list, Int32 D10ID) { // 从字典取对应连接,赋值给方法内局部变量,不会被其他线程修改 if (!_d10ConnDict.TryGetValue(D10ID, out SQLiteConnection localConn)) { DataProcessor.WriteLog("参数错误", $"DownloadListSiteFromDB: 未找到D10ID={D10ID}对应的数据库连接"); return false; } try { string sql = @" 你的原SQL语句保持不变即可 "; using (SQLiteCommand command = new SQLiteCommand(sql, localConn)) { // 加状态判断避免重复打开已打开的连接 if (localConn.State != System.Data.ConnectionState.Open) { localConn.Open(); } using (SQLiteDataReader reader = command.ExecuteReader()) { // 你的原数据读取逻辑保持不变即可 } } } catch (Exception ex) { DataProcessor.WriteLog("Error Catching", "DownloadListSiteFromDB: DB Error D1 - Exception: " + D10ID + " " + ex.Message); return false; } // 注意:如果每个D10ID仅对应唯一线程访问,不需要每次查询都关闭连接,保持常开性能更好 // 如果需要关闭,也操作局部变量localConn,不要操作任何共享变量 finally { // localConn.Close(); } return true; }
额外优化建议
- SQLite的读操作本身是线程安全的,但连接对象不是线程安全的,你当前每个D10ID对应独立连接、独立线程的架构是合理的,只要避免共享连接变量就不会有并发问题
- 后续新增D10ID只需要在连接字典里加一条配置即可,不需要修改大量if-else判断,维护成本更低
内容的提问来源于stack exchange,提问作者nickshim06
相关产品推荐
相关产品推荐

