使用解构者是错误的

本文关键字:错误 | 更新日期: 2023-09-27 17:49:36

我有一些文件被写入c#中的临时位置。然后将它们渲染为pdf缩略图。当对象被销毁时,我想清理位置,所以在这个例子中使用解构器可以吗?

    ~Foo()
    {
        try
        {
            Directory.Delete(path, true);
        }
        catch (IOException ex)
        {
            Console.WriteLine("exception: " + ex.Message + " . from: Foo_Closing");
        }

使用解构者是错误的

即使它与C++析构函数具有相同的语法——这是C#中的终结器,当对象在终结时被垃圾收集时运行——这将对性能产生影响,因为GC必须运行一个单独的线程来运行所有终结器,要做到这一点,您的对象实例将比必要的生存时间更长。

话虽如此,如果不是绝对必须的话,就不应该使用它——一个例外是当你必须处理资源时,在这种情况下,你的类也应该实现IDisposable。这将允许类的使用者将其封装在using块中,该块将调用Dispose()——这是您应该拆除资源的地方。

您应该实现IDisposable接口,并在其中进行清理。

解构器(也称为析构函数或终结器(的问题是,您无法预测它们何时运行,因为它们是由垃圾收集器调用的。为了具有可预测的行为,您应该实现IDisposable并显式调用Dispose(或在using块中使用对象(

如果没有显式调用Dispose,也可以从析构函数中调用它。有关要使用的推荐模式,请参阅此页。

我可能只会使用环境的临时文件/文件夹位置,这样用户或管理员就可以在正常内务处理过程中清理文件。

不要麻烦这样做,因为这有点像黑客攻击——然后删除文件夹真的有那么重要吗?

尽可能避免实现的finalzer。您无法控制何时调用它们,并且它们会导致性能损失,因为运行时需要专门使用终结器处理对象。通常,只有当您有一个本机对象句柄或其他需要清理的本机资源时,才应该实现终结器。

相反,在类上实现IDisposable接口,将清理代码移动到Dispose方法,并确保所有客户端都调用Dispose方法(using语句非常方便(。

实现IDisposable接口istead:

public class tester : IDisposable
{
    #region IDisposable Members
    public void Dispose()
    {
        //cleanup code here
    }
    #endregion
}
using (tester t = new tester())
{
}
//tester now disposed 

但不要忘记MSDN中的这一宝贵知识:

因为Dispose方法必须显式调用,对象实现IDisposable还必须实现一个终结器来处理在Dispose不为时释放资源称为

因此,您还应该实现终结器和IDisposable接口,记住两者都将被调用。

为什么不使用IDisposable接口,然后你可以用"using"包装你的调用,Dispose((将执行执行所需的所有清理

public class Foo : IDisposable{public void Dispose() { //Clean up here}
}

using (foo = new Foo() ) { //consume foo here }

如果您能够利用这一点,那么关闭时可以删除临时文件,对吗?尝试这些链接

  1. 使用临时文件流进行处理
  2. http://msdn.microsoft.com/en-us/library/system.io.fileoptions.aspx
  3. http://www.codeproject.com/KB/system/Taking_care_of_temp_files.aspx?msg=3489384