我面临与您相同的认识,并且将不得不做类似的事情。我认为您的代码没有问题。
我将尝试使用 ConcurrentDictionary 进行一些优化。它应该允许我在更新时避免锁定读者。
如果您继续使用 Dictionary,您可能希望将 ContainsKey() 调用更改为 TryGetValue(),因为文档表明如果使用不存在的键可能会更有效(我们经常会看到新线程?)
如果其他人开车经过,这里是我对这个问题的背景研究:Microsoft.Data.Sqlite 派生自 ADO.NET 对象,例如 DbConnection,根据设计,它不是线程安全的。ADO.NET 的设计者在高性能的祭坛上牺牲了线程安全。出于这个原因,任何使用从 ADO.NET 派生的任何东西的代码最终都需要进入这个兔子洞,以确保不会发生真正奇怪的事情。
至于 Microsoft.Data.Sqlite 我的问题是 SqliteCommand.Dispose 内部遇到 null 并崩溃。这是框架在不同线程上进行大量并行调用的时候。
您可能还注意到 sqlite 本身具有多线程设置,并相信这个兔子洞是适合您的。不幸的是,摆弄这些设置,尽管它们可能是有益的,但并没有改变 ADO.NET 对象设计,因此只要您使用 Microsoft.Data.Sqlite 访问 sqlite,问题就仍然存在。
感谢您发布您的代码!希望它能够成功地投入生产:-)
/尼克
发布后添加:持有对 Thread 和 SqliteConnection 的引用的字典将对资源产生影响,因为只要引用存在,它就会停止垃圾收集回收它们的资源。SqliteConnections 也是如此。可能不是一个真正的问题,但人们可能还想考虑某种清理算法,该算法将在一段时间后删除陈旧的线程引用。SqliteConnections 如果移过来并单独存储,仍然可以重复使用。
/尼克