如果不处理HttpContext.Current.Items会发生什么?

7

我正在使用HttpContext.Current.Items基于已登录的用户来设置租户。为此,我使用以下代码:

protected virtual void Application_BeginRequest()
{
    HttpContext.Current.Items["_CurrentTenant"] = Tenant.GetCurrent();
}

protected virtual void Application_EndRequest()
{
    var currentTenant = HttpContext.Current.Items["_CurrentTenant"] as Tenant;
    if (currentTenant != null)
        currentTenant.Dispose();
}

考虑到HttpContext.Current.Items只存在于当前请求中,因此预计它会在请求完成后被销毁。而且,CurrentTenant对象是一个完全托管的对象。

因此,在EndRequest中释放它是必需的吗?如果不这样做会发生什么?


1
当然我尝试过了,但没有明显的效果。我在想,例如省略它是否会导致内存泄漏。此外,如果租户对象本来就不可处理,那么这样做是否有意义。 - Martin de Ruiter
你在最后一句话中想要表达什么意思:“此外,如果Tenant对象本身不可处理,这是否有意义”?Tenant对象是IDisposable类型的吗? - MindSwipe
1
经验法则:如果一个对象继承自IDisposable接口,在其超出作用域时一定要进行处理。如果没有,就让垃圾回收器来处理它。 - MindSwipe
租户对象不从iDisposable继承。所以在这种情况下,我可以假设GC会处理它,而您不需要处置它(即使它存在于HttpContext.Current.Items中)吗? - Martin de Ruiter
你可以考虑一下使用 DisposeOnPipelineCompleted 方法,该方法可以告诉 ASP.NET 在请求完成后释放一个项目。 - John Wu
显示剩余3条评论
1个回答

0
因此,在EndRequest中需要处理吗?
只有您自己知道,在请求结束时处理对象是否是您想要的。确保在不再使用时进行处理。如果在请求结束时,那么可能是一个好的位置。
如果不这样做会发生什么?
.Dispose()方法将不会被调用。对于您的特定类来说,这意味着什么只有您自己能够说出来。正常的模式会在终结器中调用.Dispose(),但在此之前,可能需要一段时间。在此期间发生的情况完全取决于为什么首先将其标记为IDisposible。也许文件没有关闭,连接可能仍然打开,句柄可能没有返回...只有您自己知道它是否是您的类。

租户对象不继承自iDisposable。那么在这种情况下,我可以假设GC会处理它,而您不需要处理它(即使它存在于HttpContext.Current.Items中)吗? - Martin de Ruiter
很抱歉,我不理解你的问题。如果它没有实现IDisposable接口,那么它就不能被处理。你是不是指“垃圾回收”?是的,当最后一个引用离开作用域时,每个对象都会自动发生垃圾回收。 - nvoigt
@MartindeRuiter 是的,您只需要处理那些具有IDisposable接口的对象以及实现该接口的对象,因为它们可能会持有昂贵的资源,例如数据库连接。 - JoshBerke
我基本上担心的是,如果你只在BeginRequest中设置HttpContext.Current.Items,并且没有在任何地方(例如EndRequest)删除、释放或让它进行垃圾回收,那么这将导致内存泄漏。或者,如果您使用完全托管的代码(我的Tenant对象是),GC是否会处理它? - Martin de Ruiter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接