【发布时间】:2016-04-26 02:00:51
【问题描述】:
我正在编写一个针对 Entity Framework 6.1.3 的 C# .NET4.5 控制台应用程序。 我使用的工作单元范式如下:
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DataContext _context;
private readonly List<object> _repositories = new List<object>();
public UnitOfWork(DataContext context)
{
_context = context;
_context.Configuration.LazyLoadingEnabled = false;
}
public IRepository<T> GetRepository<T>() where T : class
{
//try to get existing repository
var repo = (IRepository<T>)_repositories.SingleOrDefault(r => r is IRepository<T>);
if (repo == null)
{
//if not found, create it and add to list
_repositories.Add(repo = new EntityRepository<T>(_context));
}
return repo;
}
public int Commit()
{
return _context.SaveChanges();
}
public bool AutoDetectChanges
{
get { return _context.Configuration.AutoDetectChangesEnabled; }
set { _context.Configuration.AutoDetectChangesEnabled = value; }
}
我的存储库是这样的:
public class EntityRepository<T> : IRepository<T> where T: class
{
protected readonly DbContext Context;
protected readonly DbSet<T> DbSet;
public EntityRepository(DbContext context)
{
Context = context;
DbSet = Context.Set<T>();
}
public IQueryable<T> All()
{
return DbSet;
}
….. other functions….
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = Context.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
}
我这样称呼它们:
var rep = _uow.GetRepository<TableOfPies>();
rep.Add(Pie);
_uow.Commit();
我的控制台应用程序有多个线程,每个线程都会在某些时候想要更新/编辑/添加到我基于云的 SQL Server 数据库中的相同表中。
我已经使用锁为我的其他代码实现了线程安全代码,但我不知道如何使实体线程安全?现在,我收到以下错误:
INNER EXCEPTION: New transaction is not allowed because there are other threads running in the session.
我上网查了一下,并没有找到很多关于实体和多线程的信息。我听说 Entity 不支持多线程应用程序,但我觉得这很可信。任何指针将不胜感激。
【问题讨论】:
-
我会注意到多线程只会改善 CPU-bound 任务。由于数据库任务通常受 I/O 限制(对于“云”数据库更是如此),多线程可能没有多大帮助,如果多线程的开销超过了任何好处,甚至可能更糟糕。
-
@DStanley 这并不完全正确。我一直在 I/O 任务上使用多线程,并发现了巨大的好处。这样做的好处是,在您等待一个查询的回复时,您可以准备并发送下一个查询。当然,这实际上并不依赖于多个线程。它更像是多任务处理,尽管它通常看起来相同。我真的很喜欢 .NET 中的新任务库。我的代码好像是多线程的,但框架会处理它实际使用的线程数。
标签: c# multithreading entity-framework