C# 实体框架:如何防止多线程访问dbcontext?

C# 实体框架:如何防止多线程访问dbcontext?,c#,.net,multithreading,entity-framework,C#,.net,Multithreading,Entity Framework,我正在使用异步并等待多线程 如果我在单线程上使用Async和Wait,它可以正常工作,但当我使用多个线程时,它会出现错误,即我试图使用多个线程访问dbcontext 我知道我不能那样做。但现在我需要一个调度器,它将dbcontext的访问调度到每个线程 如何编写此类调度器/互斥器或解决此问题的任何东西。这与其说是一个答案,不如说是帮助[用户]的信息 也 DbContext不是线程安全的 决不能同时从多个线程访问DbContext派生的实例。这可能导致通过同一数据库连接并发发送多个查询。它还将损坏

我正在使用异步并等待多线程

如果我在单线程上使用Async和Wait,它可以正常工作,但当我使用多个线程时,它会出现错误,即我试图使用多个线程访问dbcontext

我知道我不能那样做。但现在我需要一个调度器,它将dbcontext的访问调度到每个线程


如何编写此类调度器/互斥器或解决此问题的任何东西。

这与其说是一个答案,不如说是帮助[用户]的信息

DbContext不是线程安全的

决不能同时从多个线程访问DbContext派生的实例。这可能导致通过同一数据库连接并发发送多个查询。它还将损坏DbContext维护的一级缓存,以提供其身份映射、更改跟踪和工作单元功能

在多线程应用程序中,必须在每个线程中创建并使用DbContext派生类的单独实例

因此,如果DbContext不是线程安全的,它如何支持EF6引入的异步查询特性呢?只需防止在任何给定时间执行多个异步操作(如实体框架规范中关于异步模式支持的文档所述)。如果您试图在同一个DbContext实例上并行执行多个操作,例如通过DbSet.toListSync()方法并行启动多个SELECT查询,您将得到一个NotSupportedException,并显示以下消息:


在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全

实体框架的异步特性支持异步编程模型,而不是启用并行性

摘自EF文章:

线程安全性

虽然线程安全会使异步变得更有用,但它是一种正交特性。鉴于EF与由用户代码组成的图形交互以维护状态,并且没有简单的方法确保此代码也是线程安全的,因此我们不清楚在最普遍的情况下是否能够实现对它的支持


目前,EF将检测开发人员是否试图同时执行两个异步操作并抛出。”

这与其说是一个答案,不如说是帮助[用户]的信息

DbContext不是线程安全的

决不能同时从多个线程访问DbContext派生的实例。这可能导致通过同一数据库连接并发发送多个查询。它还将损坏DbContext维护的一级缓存,以提供其身份映射、更改跟踪和工作单元功能

在多线程应用程序中,必须在每个线程中创建并使用DbContext派生类的单独实例

因此,如果DbContext不是线程安全的,它如何支持EF6引入的异步查询特性呢?只需防止在任何给定时间执行多个异步操作(如实体框架规范中关于异步模式支持的文档所述)。如果您试图在同一个DbContext实例上并行执行多个操作,例如通过DbSet.toListSync()方法并行启动多个SELECT查询,您将得到一个NotSupportedException,并显示以下消息:


在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全

实体框架的异步特性支持异步编程模型,而不是启用并行性

摘自EF文章:

线程安全性

虽然线程安全会使异步变得更有用,但它是一种正交特性。鉴于EF与由用户代码组成的图形交互以维护状态,并且没有简单的方法确保此代码也是线程安全的,因此我们不清楚在最普遍的情况下是否能够实现对它的支持


目前,EF将检测开发人员是否试图一次执行两个异步操作并抛出。”

您肯定可以将EF与
async/await一起使用,但是

就性能而言,这似乎是您使用
async/await
的原因


对于这个例子,我建议只为每个
CallToDbOps()

创建两个单独的上下文,您肯定可以将EF与
async/await
一起使用,但是

就性能而言,这似乎是您使用
async/await
的原因


对于本例,我建议只为每个
CallToDbOps()

创建两个单独的上下文。您是否从不同的线程访问相同的
DbContext
?可能您忘记了添加
configurewait(false)
以捕获上下文是的,Fedeico DipumaAiska Hendra,我也更新了代码您是否从不同的线程访问相同的
DbContext
?您可以附加代码吗?也许你忘了添加
configureawait(false)
来捕获上下文是的,Fedeico DipumaAiska Hendra,我也更新了代码,这是否意味着我不能使用EF的多重预测?我需要停止使用EF吗?如何使用Wait?我使用了wait everywhere,但它仍然声称上下文正在与多个线程一起使用EF6+中的async的问题是,每个线程必须等待其他线程,然后才能启动查询,即它们无法在中工作