首页 文章

在高容量IIS网站上运行时,实体框架是否会失败

提问于
浏览
2

我们一直试图分析这个例外:

消息:错误:对象引用未设置为对象的实例.StackTrace:在System.RuntimeType.CreateInstanceSlow中的System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,Boolean publicOnly,Boolean noCheck,Boolean&canBeCached,RuntimeMethodHandleInternal&ctor,Boolean&bNeedSecurityCheck) (布尔值publicOnly,布尔skipCheckThis,布尔fillCache)在System.RuntimeType.CreateInstanceDefaultCtor(布尔值publicOnly,布尔值skipVisibilityChecks,布尔skipCheckThis,布尔fillCache)位于Z.Services.ObjectContextManagement.ScopedObjectContextManager1.get_ObjectContext()的System.Activator.CreateInstanceT中 . Z.Services.DatabaseAccess.DatabaseAccess`2.get_ObjectContext()上的Services.DatabaseAccess.DatabaseAccess2.Manage()

基本上我们在获取ObjectContext时会出错 .

从这个问题:Entity Framework lazy loading doesn't work from other thread我们看到EF依赖于保持在同一个线程上 .

从这个Jon Skeet对这个问题的回答:Will a request in IIS run on a single thread?我们看到IIS具有线程敏捷性 .

当流量较低时,我们看不到此错误,但是当负载增加时,我们会看到错误 .

所以问题是:如果EF依赖于保留在单个线程上,并且IIS不将请求保留在单个线程上,那么可以在IIS上部署的应用程序上使用EF吗?

Edit

var frameworkAssembly = Assembly.GetAssembly(typeof(ObjectContextManager<>));
var managerType = frameworkAssembly.GetType(managerTypeName + "`1", true, true);
managerType = managerType.MakeGenericType(typeof(TObjectContext));
ObjectContextManager = Activator.CreateInstance(managerType) as ObjectContextManager<TObjectContext>;

看来错误发生在上面代码的最后一行 . 该错误仅发生在重负载下的 生产环境 中 .

Edit 2

ObjectContextManager继承自ObjectContext,它是一个EF类 .

public abstract class ObjectContextManager<T> where T : ObjectContext

1 回答

  • 3

    我最近遇到了线程敏捷和IIS的一些问题 . IIS可以在请求通过管道时移动它的线程 . 这并不意味着您必须更加了解并发性;重要的是上下文数据附加到线程的方式 .

    在ASP.NET环境中,此存储通过 HttpContent.Current 变量完成,该变量保存当前线程上正在处理的当前请求的详细信息 . 它通过 System.Runtime.Remoting.Messaging.CallContext.HostContext 变量完成此操作 .

    用于保持每个线程数据的许多解决方案都使用 ThreadStatic 属性,但是由于线程切换,这在ASP环境中失败 . 线程静态开始关闭值,然后在处理管道的中途显示为 null .

    ASP.NET将跟踪 HttpContextCurrentPrincipal 以及可能的语言环境 . 不复制 CallContext 存储在 ThreadStatic 变量中的数据和数据 .

    答案虽然令人恼火,但是要改变策略并使用 HttpContext.Current.Items 而不是 CallContext 或线程静态 .

    在您的情况下,请检查EF使用的策略,并查看实现是否可插入 .

    正如Jon Skeet指出的那样,更多的信息可以在Cup(Of T)上找到,但是更多的信息可以用作发现的启动板而不是目的 .

相关问题