【发布时间】:2012-06-20 10:15:59
【问题描述】:
我们一直在尝试分析这个异常:
消息:错误:对象引用未设置为对象的实例。 堆栈跟踪:在 System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 在 System.RuntimeType.CreateInstanceSlow(布尔 publicOnly,布尔 skipCheckThis,布尔型填充缓存)在 System.RuntimeType.CreateInstanceDefaultCtor(布尔 publicOnly, 布尔型 skipVisibilityChecks,布尔型 skipCheckThis,布尔型 fillCache) 在 System.Activator.CreateInstanceT 在 Z.Services.ObjectContextManagement.ScopedObjectContextManager
1.get_ObjectContext() at Z.Services.DatabaseAccess.DatabaseAccess2.Manage() 在 Z.Services.DatabaseAccess.DatabaseAccess`2.get_ObjectContext()
基本上我们在获取 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 不会将请求保持在单个线程上,那么 EF 可以在部署在 IIS 上的应用程序上使用吗?
编辑
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>;
似乎错误发生在上述代码的最后一行。该错误仅发生在重负载下的生产中。
编辑 2
ObjectContextManager 继承自 ObjectContext,它是一个 EF 类。
public abstract class ObjectContextManager<T> where T : ObjectContext
【问题讨论】:
-
鉴于 EF IS 部署在很多网站上都没有问题,你应该检查一下你做错了什么。你能显示有问题的代码吗?
-
@PanagiotisKanavos 感谢您的评论,我已经更新了问题
-
这不是 EF 代码。这是关于 Activator 未能创建类型。你确定 managerType 不为空吗?顺便说一句,什么是 ObjectContextManager?你为什么要创建这样的课程?为什么不直接将上下文类型作为类型参数传递?
-
我不明白这个“线程敏捷性”是什么意思。我需要关心吗?我希望 IIS 必须管理此类线程更改,而无需我对任何同步进行编程。可怕,如果你的问题真的是由 IIS 基础设施引起的......
-
EF 不是线程安全的,这意味着您不能在多个线程中使用相同的 ObjectContext 实例(或其他常见的 EF 对象,如 ObjectStateManager 等)。但是,如果您为每个线程创建一个单独的 ObjectContext 实例,那么您应该没问题。正如之前有人在您的堆栈跟踪和您的示例中指出的那样,您正在使用任何属于 EF 的东西。
标签: c# multithreading entity-framework iis objectcontext