【问题标题】:C# Writing to database in async ForEach LoopC# 在异步 ForEach 循环中写入数据库
【发布时间】:2019-01-02 20:21:38
【问题描述】:

我的数据库中有一个名为 devices 的表,EF 在我的项目中创建了该表的模型。我有一个称为元素的字符串列表,我需要通过这个元素循环异步并进行检查,然后根据结果更新设备对象的属性,在每次迭代开始时我创建设备模型的新实例,在准备好我需要的设备对象之后在我的数据库中查询我的设备表以获取相同元素的所有记录,然后根据新对象更新所有记录。当我尝试在我的数据库中查询我的设备表时,我收到了这个异常

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

这是我的代码流程

static async void Begin(List<string> elements)
{
ParalelForEach(elements, element => {

devices devObj = new devices();
//here i do my operation on element and update devObj object
// now in below i should query my device table in my database to collect all records of same element so I can update them based on new devObj i created but above Exception thrown

var dbElementsList = dbContext.devices.Where(e =>e.name == element).Tolist();//Exception is thrown here

foreach(var dbe in dbElementsList)
{
//update process happens here on dbe
}
dbContext.devices.Add(devObj);
dbContext.SaveChanges();

}):
}

【问题讨论】:

标签: c# asp.net-mvc asynchronous


【解决方案1】:

DbContext 不是线程安全的。它使用到数据库的单个连接,并且您不应该从多个线程访问单个连接实例(特殊类型的连接有例外,但最好假设您不应该并且绝对不能)。

要并行化对 db 的调用,您需要在 Parallel.ForEach 的主体中创建一个新的 DbContext 实例。

【讨论】:

  • 您能详细说明一下吗? @尼克
  • 警告:如果集合很大,每个执行线程的新 DbContext 可能无法很好地扩展,并且可能仍会遇到数据库中的表锁。
  • 因为它在同一个地方抛出另一个错误“目标主体名称不正确。无法生成 SSPI 上下文。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多