如何在处理对象之前执行操作?

时间:2010-11-22 16:40:55

标签: c# garbage-collection dispose abstract

使用C#。我有一个抽象类,用于读取/写入xml文件的设置。当不再需要该类时,我希望在类处理之前对xml文件执行最后一次写操作。我尝试将此代码放在析构函数方法~myClass() {}中,但它会抛出一个异常,说安全句柄已关闭。我猜这意味着这个班级已被处置或部分处置。因此,如果析构函数不是正确的位置,那么正确的位置在哪里?我是否需要实现IDisposable或其他什么?

4 个答案:

答案 0 :(得分:3)

在C#中没有destructor s这样的东西。请参考Jon Skeet的这个问题接受的答案,他解释并提供了一篇关于该主题的好文章。 Sample use of a C# Destructor

此外,或许您应该考虑在班级中实施IDisposable界面,以便您可以执行操作。

答案 1 :(得分:2)

在SO上有很多关于终结器的线程,只读了一些。

基本点是你不应该依赖终结器,因为它们的执行顺序是未定义的,或者可能根本不运行。对于本地资源,您应该使用IDisposable进行任何托管清理(您的情况)和SafeHandles / CriticalFinalization。

答案 2 :(得分:0)

听起来好像今天你试图使用SafeHandle字段写出对象终结器中的设置文件。这不是正确的方法。

一旦对象命中CLR终结器线程,所有下注都将关闭对象可以看到的其他受管资源。 SafeHandle字段已经最终确定是非常合法的,因此在包含类的终结器运行时无效。

使用这样的方案的标准方法是实现IDisposable并使用Dispose方法(用户代码调用)来正确处理托管资源,例如文件。

例如:

abstract class MyClass : IDisposable { 

  private SafeFileHandle _handle;

  public void Dispose() { 
    WriteTheFile();
    _handle.Dispose();
  }

}

答案 3 :(得分:0)

如果你需要让终结器让你有机会在文件关闭之前写一些东西,你需要确保对文件的强引用会比你的对象更长。一种方法是在静态字段中存储对文件的强引用。当对象的终结器运行时,您可以编写数据,关闭文件并清空静态字段。请注意,如果终结器无法将该字段置空,无论出于何种原因,该文件可能会无限期地保持打开状态。