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 继承自一个 EF 类 ObjectContext。
 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 将跟踪 HttpContext , CurrentPrincipal ,也可能是语言环境。 CallContext数据和数据存储在ThreadStatic不复制变量。

答案虽然很烦人,但是改变策略,使用HttpContext.Current.Items而不是 CallContext或线程静力学。

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

正如 Jon Skeet 所指出的,更多信息可在 Cup(Of T) 上获得。 ,但更多地将其用作发现的启动板,而不是目的本身。

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

相关文章:

c++ - 回调为单例类

c - 多线程程序使用者导致程序卡住

c# - 设计师问题 + Entity Framework (WPF MVVM)

entity-framework - 即使禁用了自动迁移,Update-Database 也会尝试进行自动迁移

c# - 15分钟后应用程序崩溃,WCE 6.0 CF 3.5 Motorola MC3190

c# - 冲突的命名空间解析

c# - TransactionScope TransactionAborted异常-事务未回滚。应该是吗?

c# - HtmlHelper 扩展来环绕 ServiceStack Markdown Razor 的内容

c++ - 传递给新线程的结构具有错误的值

entity-framework - EF6 生成用于部署到生产的种子数据