创建ThreadLocal EF上下文

时间:2014-01-23 11:18:11

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

我一直在使用Entity Framework调用时遇到一些奇怪的错误,我正在探索它们是由于使用相同的ObjectContext并发多线程访问所致。

我试图通过将创建上下文放在ThreadLocal中来为每个线程创建一个新的上下文。

private System.Threading.ThreadLocal<EF.XYZEntities> threadLocalContext = new System.Threading.ThreadLocal<EF.XYZEntities>(() => new EF.XYZEntities(connectionString));
private EF.XYZEntities context { get { return threadLocalContext.Value; } }

这不起作用。第一次使用该上下文会引发错误:

  

无效的对象名称'dbo.Site'。

我怎样才能让它发挥作用?

1 个答案:

答案 0 :(得分:1)

使用共享上下文通常被认为是“糟糕”,除非您对所有内容进行微观管理。使用不能很好管理的共享上下文会产生非常奇怪的结果。

通常最佳做法是采用工作单元方法,具体情况如下:

using (DBEntities ctx = new DBEntities())
{
    // Explicitly open the context connection yourself - to help prevent connection pooling / sharing
    // The connection will automatically be closed once exiting the using statement,  
    // but it won't hurt to put a ctx.Connection.Close(); after everything inside the using statement.
    ctx.Connection.Open();

    // Do Stuff

    // If necessary ctx.SaveChanges();
    // Not necessary but you could put a ctx.Connection.Close() here, for readability if nothing else.
}

更新:回复Noseratio下面关于异步和EF的评论。 Taken from here

<强>非目标

以下是我们明确未尝试使用EF6中的功能启用的内容:

  • 线程安全
  • 异步延迟加载

线程安全

虽然线程安全会使异步更有用,但它是一个正交特征。目前还不清楚我们是否可以在最常见的情况下实现对它的支持,因为EF与用户代码组成的图形交互以维持状态,并且没有简单的方法来确保此代码也是线程安全的。

目前,EF将检测开发人员是否尝试同时执行两个异步操作并抛出....

EF中的异步支持需要.NET 4.5,并且在.NET 4上不可用。