【发布时间】:2018-02-15 12:22:53
【问题描述】:
我正在开发一个实体框架中的多线程程序,其中我面临一个问题。我有一个多个数据库的列表,对于每个数据库我需要执行一些操作(插入/更新),目前我面临线程之间的竞争条件问题,其中我得到实体框架的错误。
异常:- 底层提供程序在打开时失败。
InnerException :- 连接没有关闭。连接的当前状态为正在连接。
我用过static readonly object Locker = new object();
lock (Locker)
但这会一个一个地执行线程。有什么方法可以一次生成所有线程,而不会出现实体框架错误,即在线程隔离中执行。
我的代码如下
var keyController = _empUnitOfWork.Repository<KeyController>()
.Get(x => x.Type.Equals("X") && x.IsOnline).AsNoTracking().ToList();
var taskList = new Task[keyController.Count];
for (var i = 0; i < keyController.Count; i++)
{
var idx = i;
var otherUnitOfWork = new TestUnitOfWork(_logger);
otherUnitOfWork.SetSiteDbContext(_empUnitOfWork, keyController[idx].Id);
taskList[idx] = Task.Factory.StartNew(() =>
{
OtherMethodToBeExecutedOnMultipleThread(keyController[idx], otherUnitOfWork);
});
}
// Wait for all tasks to complete.
Task.WaitAll(taskList);
【问题讨论】:
-
我知道您使用的是 EF,但您是否在任何时候都将
SqlConnection声明为类变量,然后在多个方法中重用它? -
here 是一些解决方案。
-
您的变量
_logger和_empUnitOfWork是线程安全的吗?它们可能同时用于多个线程。 -
尤其是
SetSiteDbContext看起来很可疑......真的为每个工作单元设置相同的DbContext吗? -
你说“线程隔离执行”对我来说是一个奇怪的短语。 进程是操作系统的隔离单元。 thread 是操作系统的execution 单元。如果您需要隔离,请使用进程。
标签: c# multithreading entity-framework-6 task-parallel-library