【问题标题】:Using a single context from many threads in Entity Framework 6在 Entity Framework 6 中使用来自多个线程的单个上下文
【发布时间】:2018-04-04 04:02:11
【问题描述】:

有没有办法在不同的线程中异步使用一个 dbContext?

 var context = new Entities();
 Task.Factory.StartNew(() => context.Companies.Include(x => x.Address).First());
 Task.Factory.StartNew(() => context.Companies.Include(x => x.Owner).First());
 //after some changes...
 context.SaveChanges();
 context.Dispose();

主要思想是立即保存所有内容,如果某些内容无法返回所有更改。 实际上,我使用的是传递给 viewmodel 及其子视图模型的工作单元对象,因此它们尝试异步获取信息......上面的代码说明了这个问题。 上面的代码会抛出异常:

EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理 创建模型时不能使用上下文。如果在 OnModelCreating 方法中使用上下文,或者多个线程同时访问同一个上下文实例,则可能会引发此异常。请注意,不保证 DbContext 和相关类的实例成员是线程安全的。

主要问题是如果我想使用多个 DbContext 实例,每个数据传输对象都将包含不同的字段信息。 有什么建议么? 谢谢!

【问题讨论】:

    标签: c# multithreading entity-framework thread-safety


    【解决方案1】:

    上下文不是线程安全的。时期。因此,永远不要处理来自多个线程的上下文,也不要跳过箍来尝试使其成为线程安全的。

    您可以简单地将代码包装在 TransactionScope 中,并使用创建自己的上下文并保存其更改的操作来启动每个 Task

    using (var tran = new TransactionScope())
    {
        Task.Factory.StartNew(() => DoSomething());
        Task.Factory.StartNew(() => DoSomethingElse());
        // Wait all
        tran.Complete();
    }
    

    【讨论】:

    • 谢谢,你的想法在我脑海中浮现,但是当 SaveChanges() 的最后一次 SaveChanges 出现时,会抛出一个异常,上面写着“语句影响了意外的行数 (0)。实体可能已被修改或在实体加载后被删除。”
    • 这意味着你已经成为你自己的并发用户。您从不同的线程更新相同的记录。
    • @Teomanshipahi 使用lock,在哪里?无论如何,不​​,甚至不要尝试以线程安全的方式使用上下文。
    • @GertArnold 明白了,最好使用“每个线程的上下文”解决方案。
    • 我们可以创建一个新线程来执行第二个操作,而不是使用TransactionScope
    【解决方案2】:

    如果您使用 SimpleInjector 来获取 DbContext 的实例,那么您将遇到线程安全问题。

    对于这种情况,您需要使用 ThreadScopedLifestyle 并封装您的代码。见:

    Container container = new Container();
    container.Options.DefaultScopedLifestyle = new     SimpleInjector.Lifestyles.ThreadScopedLifestyle();
    container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
    
    using (SimpleInjector.Lifestyles.ThreadScopedLifestyle.BeginScope(container))
    {
        var _uow = container.GetInstance<IUnitOfWork>();
        // put your business code here ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-18
      • 2014-03-15
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      相关资源
      最近更新 更多