Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “;在此上下文上启动了第二个操作”;EF core 3.1并发中断更改_C#_.net Core_Async Await_Entity Framework Core - Fatal编程技术网

C# “;在此上下文上启动了第二个操作”;EF core 3.1并发中断更改

C# “;在此上下文上启动了第二个操作”;EF core 3.1并发中断更改,c#,.net-core,async-await,entity-framework-core,C#,.net Core,Async Await,Entity Framework Core,我正在从netcoreapp 2.1迁移到3.1,我发现EF core 3.1有一个无法解决的突破性变化以下内容在2.1中起作用,因此简单地说db上下文在设计上不是线程安全的,并指出其他不涉及这种细微差别的问题并不能解决当前的问题。 在之前的2.1中,这是有效的: taskList.Add(MethodOne(myRequestObject)); taskList.Add(MethodTwo(myRequestObject)); await Task.WhenAll(taskList); 其

我正在从netcoreapp 2.1迁移到3.1,我发现EF core 3.1有一个无法解决的突破性变化以下内容在2.1中起作用,因此简单地说db上下文在设计上不是线程安全的,并指出其他不涉及这种细微差别的问题并不能解决当前的问题。

在之前的2.1中,这是有效的:

taskList.Add(MethodOne(myRequestObject));
taskList.Add(MethodTwo(myRequestObject));

await Task.WhenAll(taskList);
其中两种方法都只从db上下文中读取(从未更改),如下所示:

private async Task MethodOne(RequestObject myRequestObject)
{
    var entity = await DbContext
    .MyDbSet
    .OrderByDescending(x => x.SomeProperty)
    .FirstOrDefaultAsync(x => x.Id == myRequestObject.Id);

    if (entity != null)
        myRequestObject.SomeRequestProperty = entity.AnotherProperty;
    }
}
在3.1中,即使我只是读取实体而没有更改实体,DB context ConcurrencyDetector也认为它有
EnterCriticalSection
,这会在第二个方法尝试在DbContext上等待时导致异常:

InvalidOperationException:在此上下文上启动了第二个操作 在上一个操作完成之前

对于基线健全性,我还尝试了以下方法,这些方法确实有效(但对于我的应用程序的实际代码来说,这不是一个理想的解决方案):

下面是我的问题:

  • 如果我知道并发是安全的,是否有办法继续告诉EF core 3.1允许并发这在2.1中起到了作用,因此很明显,不能简单地说db上下文从未允许通过设计实现这一点,并以重复的方式结束问题。我的应用程序已经在生产中愉快地运行了很长时间。只有在迁移到3.1之后,这才成为一个问题。发生了什么变化?这种改变真的不可能解决吗?或者说上下文不允许这样做的说法有例外吗?如果这在“设计不允许”的情况下曾经奏效,那么现在也有可能同样不成立吗?
  • 如果我知道并发是安全的,是否有办法继续告诉EF core 3.1允许并发。这在2.1中起到了作用,因此很明显,不能简单地说db上下文从未允许通过设计实现这一点,并以重复的方式结束问题

    DB上下文从未允许这样做。我从未见过这种代码在任何版本的.NETCore上工作。如果它碰巧在2.x中起作用,那么它只是“起作用”了,因为代码赢得了比赛条件,因此只是运气好而已。性能上的任何变化—内存减少、防病毒软件、备用网络路由—都可能导致此操作失败。认识到代码是错误的并且一直是错误的,这一点非常重要

    我的应用程序已经在生产中愉快地运行了很长时间。只有在迁移到3.1之后,这才成为一个问题。发生了什么变化

    可能是框架中的某个时间

    如果这在“设计不允许”的时候起作用,那么现在是否也同样不可能

    竞争条件仍然存在。如果您的代码碰巧赢得了竞赛条件,您将不会看到该异常

    这种改变真的不可能解决吗?或者说上下文不允许这样做的说法有例外吗


    没有解决办法强制dbcontext处理多个同时请求。执行同时请求的正常模式是使用多个DbContext,每个同时请求一个。默认情况下,如果要将它们注入到作用域服务中,则会为每个请求创建一个新的服务。但您也可以自己创建它们,同时仍然利用.NETCore的DI框架

    像往常一样,在
    Startup.cs
    中声明您的
    DbContext
    。但是使用
    DbContext
    的服务(您正在向控制器中注入服务,对吗?)可以是单例而不是作用域,因为它不需要为每个请求注入新的
    DbContext
    。然后,服务启动的后台任务可以根据需要使用
    ScopeFactory
    创建上下文:

    using (var scope = ScopeFactory.CreateScope())
    using (var db = scope.ServiceProvider.GetRequiredService<MyDbContext>())
    {
        // do stuff with db
    }
    
    使用(var scope=ScopeFactory.CreateScope())
    使用(var db=scope.ServiceProvider.GetRequiredService())
    {
    //用数据库做一些事情
    }
    
    事实上,这一切都可以说是因为这是由负责efcore的人员进行的记录在案的(问题中的)设计变更,与许多未经深思熟虑的设计变更一样,没有人关心后果,结果留给你(以及我和其他人)。请不要重复提问。取而代之的是,你现有的问题应该包括你的推理(最好不是全部大写或全部粗体格式),为什么它不是重复的。这是包含在供参考。转载从如此简单地说实话是不可接受的?祝你好运。上下文从来都不是线程安全的。它并不总是表现出来,仅此而已。EF core 3帮助您更好地避免危险代码。@HereticMonkey当我的问题最初以副本形式结束时,我并不是按照指示这样做的。我被特别指示创建一个新问题,我的原始问题被标记为重复问题(这不是出于我所说的原因)。我不喜欢被给予不可能和矛盾的指示,被指控声称“说实话是不可接受的”,而事实上我要求答案更精确(或在驳回我的问题之前没有给出答案),以及所有其他针对这个合法问题的官僚主义攻击。
    using (var scope = ScopeFactory.CreateScope())
    using (var db = scope.ServiceProvider.GetRequiredService<MyDbContext>())
    {
        // do stuff with db
    }