c# - 在高容量 IIS 网站上运行时 Entity Framework 会失败吗

标签 c# multithreading entity-framework iis objectcontext

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

Message: Error: Object reference not set to an instance of an object.. Stacktrace: at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at 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.ScopedObjectContextManager1.get_ObjectContext() at Z.Services.DatabaseAccess.DatabaseAccess2.Manage() at 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

最佳答案

我最近遇到了线程敏捷性和 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) 上找到。 ,但更多地将其用作您发现的启动板,而不是其本身。

关于c# - 在高容量 IIS 网站上运行时 Entity Framework 会失败吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11117397/

相关文章:

c# - 为什么 Entity Framework 核心加载实体的关系而不添加包含

c# - 更改/导航到树的特定节点?

java - 在 AWT 线程中运行代码

c# - Entity Framework 代码优先的 XML 字段

asp.net 线程和 GUI

java - 通过多个线程删除 java.util.Collection 元素

c# - Entity Framework 继承和关系

c# - 在 .NET 4.0 中创建可与 .NET 4.5 中的 "await"一起使用的异步方法

c# - 在带有 .NET Core 的库 csproj 中使用 Selenium WebDriver

c# - iOS UI 的 MVVM 交叉图片选择器插件不会在 Bytes 类型 View 模型属性上使用 InMemoryImage 进行更新