【问题标题】:Is there a way to run some code as an object is being destroyed?有没有办法在对象被破坏时运行一些代码?
【发布时间】:2011-10-02 16:26:02
【问题描述】:

在 C# 中,我知道当我的对象超出范围并且不再有指向它的指针/引用时,它们会被垃圾回收。发生这种垃圾回收时有没有办法运行一些自定义代码?

【问题讨论】:

  • 是的,但您可能不应该这样做。你想做什么?
  • 附注:对象通常不会立即收集。
  • @AlexFord:那么你最好使用Dispose。如果你的终结器在DbContext 被终结之后运行会发生什么?如果程序没有耗尽内存,终结器可能会在程序结束之前运行,然后它们会以不特定的顺序运行。
  • Alex Ford:这不会像你期望的那样工作。请参阅 SLaks 的最高评论,比 Ben Voigts(技术上正确)的答案更好的建议。
  • @AlexFord:是的,你绝对应该把你的清理逻辑放在Dispose。并致电GC.SuppressFinalize(this);。然后写一个终结器,除了大声抱怨之外什么都不做,有人忘了打电话给Dispose

标签: c# .net pointers garbage-collection


【解决方案1】:

是的,它被称为终结器http://msdn.microsoft.com/en-us/library/wxad3cah.aspx

许多 C# 文档都混淆了“析构函数”一词。尽管在 C# 中使用 C++ 的析构函数命名作为终结器,但语义完全不同。如果你一直使用finalizer这个词,就不会有任何混淆。

【讨论】:

  • 宾果游戏。我想这将是一件我不知道的简单事情。谢谢本。
  • 在 C# 中它正式是析构函数。在 CLR 中,它是 Finalize 方法。令人困惑,但 dtor 是这里的正确名称。
  • 我们不要忘记警告终结器的不确定行为。你永远不知道它什么时候会被调用。 GC 调用它可能需要很长时间。
  • @Steven:那真的很糟糕。对象在同一个 GC 周期中完成的事实也可以在不考虑它们之间的引用的情况下进行处理。终结器不应假定任何其他对象仍然存在。
  • @Ben:终结器在托管代码中运行,并且由于 finalize 方法可以访问所有引用的对象,GC 必须保持它们处于活动状态(这是未处理的可终结对象可能导致内存问题的原因之一)。事实上,调用引用的对象是安全的,尽管您必须记住这些对象也可以是最终确定的。虽然安全,但在终结器中使用其他对象是一种值得商榷的方法,应该清楚地审查。
【解决方案2】:

是的。你可以为你的类定义一个终结器:

class Lava
{
    ~Lava()    // Finalizer -- runs when object is collected
    {
        // TODO: Clean up molten rock
    }
}

【讨论】:

    【解决方案3】:

    您可以使用Finalizer/Destructor (~) 方法。

    MSDN - Object.Finalize

    【讨论】:

      【解决方案4】:

      在 C# 中没有等效的析构函数 - 您可以做的最好的事情是添加一个 finalizer(具有析构函数语法),然后安排在 GC 通常收集您的对象时在专用终结器线程上执行- 这确实会导致额外的开销,并使您的对象实例的存活时间比应有的时间长。仔细考虑用例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-31
        • 2021-09-01
        相关资源
        最近更新 更多