我正在使用Async并等待多线程。
如果我在单线程上使用Async并等待它可以正常工作但是当我使用多个线程时,它会出现错误,我试图访问具有多个线程的dbcontext。
我知道我不能这样做。但现在我想要有一个调度程序,它将调度dbcontext对每个线程的访问。
如何编写此类调度程序/互斥锁或其他解决此问题的方法。
答案 0 :(得分:3)
您绝对可以将EF与async/await
一起使用,但you can't perform two operations at once on the same context。
就性能而言,it's actually faster to create two contexts看起来是您使用async/await
的原因。
对于此示例,我建议您为每个CallToDbOps()
创建两个单独的上下文。
答案 1 :(得分:0)
这不是帮助[用户] ...
的信息答案Have a read of this blog也have a read of this article about Entity Framework specifications for its async pattern support
DbContext不是线程安全的
您绝不能同时从多个线程访问DbContext派生的实例。这可能导致在同一数据库连接上同时发送多个查询。它还会破坏DbContext维护的第一级缓存,以提供其身份映射,更改跟踪和工作单元功能。
在多线程应用程序中,您必须在每个线程中创建和使用DbContext派生类的单独实例。
因此,如果DbContext不是线程安全的,那么它如何支持EF6引入的异步查询功能呢?只需阻止在任何给定时间执行多个异步操作(如实体框架规范中针对其异步模式支持所述)。如果您尝试并行执行同一个DbContext实例上的多个操作,例如通过DbSet.ToListAsync()方法并行启动多个SELECT查询,您将收到带有以下消息的NotSupportedException:
在上一次异步操作完成之前,在此上下文中启动了第二个操作。使用'等待'确保在调用此上下文中的另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
实体框架的异步功能可以支持异步编程模型,而不是支持并行性。
取自EF文章:
" 主题安全
虽然线程安全会使异步更有用,但它是一个正交特征。目前还不清楚我们是否可以在最常见的情况下实现对它的支持,因为EF与用户代码组成的图形交互以维持状态,并且没有简单的方法来确保此代码也是线程安全的。
目前,EF将检测开发人员是否一次尝试执行两次异步操作并抛出。"