实体框架:如何防止dbcontext被多个线程访问
本文关键字:线程 访问 dbcontext 框架 何防止 实体 | 更新日期: 2023-09-27 17:52:42
我正在使用异步和等待多线程。
如果我在单线程上使用Async和await,它工作得很好,但是当我使用多个线程时,它会出现一个错误,我试图用多个线程访问dbcontext。
我知道我不能那样做。但现在我想有调度程序,它将调度访问dbcontext到每个线程。我如何编写这样的调度程序/互斥锁或任何解决这个问题。
您可以对async/await
使用EF,但是您不能在同一上下文中同时执行两个操作。
在性能方面,创建两个上下文实际上更快,这看起来是您使用async/await
的原因。
对于这个例子,我建议为每个CallToDbOps()
创建两个单独的上下文。
与其说是答案,不如说是帮助[User]…
阅读一下这个博客,也阅读一下这篇关于实体框架规范对异步模式支持的文章
DbContext不是线程安全的
绝不能同时从多个线程访问dbcontext派生的实例。这可能导致通过同一数据库连接并发发送多个查询。它还会破坏DbContext为提供身份映射、变更跟踪和工作单元功能而维护的第一级缓存。
在多线程应用程序中,您必须在每个线程中创建并使用dbcontext派生类的单独实例。
如果DbContext不是线程安全的,它怎么支持EF6引入的异步查询功能呢?只需防止在任何给定时间执行多个异步操作(如实体框架规范中对其异步模式支持的文档所述)。如果您试图并行地在同一个DbContext实例上执行多个操作,例如通过DbSet.ToListAsync()方法并行地启动多个SELECT查询,您将得到NotSupportedException,其中包含以下消息:
在前一个异步操作完成之前,在此上下文中开始了第二个操作。使用'await'确保在此上下文中调用另一个方法之前,任何异步操作都已完成。不能保证任何实例成员都是线程安全的。
Entity Framework的异步特性是为了支持异步编程模型,而不是为了启用并行。
摘自EF文章:
" 线程安全
虽然线程安全将使异步更有用,但它是一个正交特性。目前还不清楚我们是否能够在大多数情况下实现对它的支持,因为EF与由用户代码组成的图交互以维护状态,并且没有简单的方法来确保这些代码也是线程安全的。
目前,EF将检测开发人员是否试图同时执行两个异步操作并抛出。"