【问题标题】:What happens if you don't dispose HttpContext.Current.Items?如果不处置 HttpContext.Current.Items 会发生什么?
【发布时间】:2019-07-06 05:11:08
【问题描述】:

我正在使用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 中进行处置?如果不这样做会怎样?

【问题讨论】:

  • 为什么不试试呢?注释掉你要处理它的行并尝试一下
  • 我当然试过,但没有明显效果。例如,我想知道省略它是否会导致内存泄漏。另外,如果 Tenant 对象无论如何都不是一次性的,这是否有意义。
  • 最后一句“另外,如果租户对象不是一次性的,这是否有意义”是 IDisposable 类型的租户对象吗?
  • 容器可能会被销毁,但如果您提取对某个项目的引用并将其存储在其他位置,只要您保留对它的引用,该项目就会一直存在。
  • 经验法则:如果一个对象从 IDisposable 继承,当它超出范围时总是将其丢弃。如果没有,让 GC 处理它

标签: c# asp.net


【解决方案1】:

所以需要在EndRequest中dispose吗?

只有你可以知道,在请求结束时处理对象是否是你想要的。确保在不再使用时将其处理掉。如果那是在请求的末尾,那么这可能是一个好地方。

如果你不这样做会怎样?

.Dispose() 方法不会被调用。这对您的特定班级意味着什么,只有您可以说。正常模式会在终结器中调用.Dispose(),但在那之前,可能需要一段时间。在那段时间发生的事情完全取决于为什么它首先被标记为IDisposible。也许文件没有关闭,连接可能保持打开状态,句柄可能不会返回......只有你才能知道它是否是你的班级。

【讨论】:

  • 租户对象不继承自 iDisposable。那么在这种情况下,我可以假设 GC 会处理它并且您不需要处理它(即使它位于 HttpContext.Current.Items 中)?
  • 恐怕我不明白你的问题。如果它没有实现 IDisposible,它不能被释放。您的意思是“收集垃圾”吗?是的,当对每个对象的最后一个引用超出范围时,它会自动发生。
  • @MartindeRuiter 是的,您只需要处理具有 IDisposable 的对象和该接口这样做的对象,因为它们可能会占用数据库连接等昂贵的资源。
  • 我基本上担心如果你只在 BeginRequest 中设置 HttpContext.Current.Items 而没有在任何地方删除、处理或让它被垃圾收集(例如 EndRequest),它会导致内存泄漏.或者如果您使用完全托管的代码(我的 Tenant 对象是),GC 是否会处理它?
猜你喜欢
  • 1970-01-01
  • 2011-08-06
  • 2019-09-27
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 2017-12-03
  • 2011-04-02
  • 1970-01-01
相关资源
最近更新 更多