2

我们一直在尝试分析这个异常:

消息:错误:对象引用未设置为对象的实例。堆栈跟踪:在 System.RuntimeType.CreateInstanceSlow(RuntimeType 类型,Boolean publicOnly,Boolean noCheck,Boolean& canBeCached,RuntimeMethodHandleInternal& ctor,Boolean& bNeedSecurityCheck)在 System.RuntimeType.CreateInstanceSlow( Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) at System.Activator.CreateInstanceT at Z.Services.ObjectContextManagement.ScopedObjectContextManager 2.Manage 1.get_ObjectContext() at Z.Services.DatabaseAccess.DatabaseAccess() 在 Z. Services.DatabaseAccess.DatabaseAccess`2.get_ObjectContext()

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

从这个问题:实体框架延迟加载在其他线程中不起作用,我们看到 EF 依赖于保持在同一个线程上。

从这个 Jon Skeet 对这个问题的回答:IIS 中的请求会在单个线程上运行吗?我们看到 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
4

1 回答 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)上提供了更多信息,但更多地将其用作您发现的启动板,而不是其本身的目的。

于 2012-10-15T12:26:22.713 回答