【问题标题】:Insert into DbContext Multithreading插入 DbContext 多线程
【发布时间】:2015-01-23 20:22:54
【问题描述】:

我在尝试从某些任务中向DbContext 添加新实体时遇到以下异常,代码在向该问题添加任务之前有效。

$exception {"模型正在运行时不能使用上下文 已创建。"} System.Exception {System.InvalidOperationException}

我做了一些研究,发现this,它包含一些对我的问题有用的信息:

此错误的另一个原因可能是在您创建上下文时 第一次,因此会导致创建您创建的模型 单独线程上的另一个上下文。您将不得不等待其他 模型创建后要创建的上下文实例 完成。

所以我想问题是等待上下文的正确方法是什么?

这是我的代码,以防我猜错了我的问题:

using(SampleEntities context = new SampleEntities())
{
    context.Configuration.LazyLoadingEnabled = false; //I tried this in case it was the problem
    Task[] TaskArray = new Task[4];
    for (int i = 0; i < TaskArray.Length; i++)
        TaskArray[i] = Task.Run(() =>
            {
                SampleEntity Result = null;
                while(this._Data.TryDequeue(out Result)) //where Data is a ConcurrentQueue<SampleEntity> with the entities to insert
                {
                    if(!context.SampleEntity.Any(/*Comparisons between properties to check if the entities values are already inserted*/)
                        context.Add(Result);
                }
            }
    Task.WaitAll(TaskArray);
    context.SaveChanges();
}

if(!context.SampleEntity.Any(...这一行抛出异常

编辑:

我有大量的寄存器以前在 _Data 中排队,如果可能的话,我试图让批量插入更快。

【问题讨论】:

  • 您说我在尝试添加新实体时遇到以下异常但忘记添加异常详细信息
  • DbContext 不是线程安全的。
  • 此外,EF 中的并行性不会给您带来任何好处,因为 EF 会为每个新值创建单独的插入,因此您将缺乏性能。
  • 这看起来像XY Problem。您的解决方案将不起作用,并且您可能无法获得所需的效果(看起来像批量插入)。或许你应该解释你想做什么,而不是你需要怎么做
  • 我添加了一个简短的解释。

标签: c# multithreading entity-framework dbcontext


【解决方案1】:

一个上下文和多个线程 - 这是一种不好的做法。最好为每个线程创建上下文。我可以建议您重新考虑您的算法并为每个线程重新创建上下文。

【讨论】: