如何使用 IDisposeable 接口释放 excel 对象

Posted

技术标签:

【中文标题】如何使用 IDisposeable 接口释放 excel 对象【英文标题】:How can release excel object with IDisposeable interface 【发布时间】:2010-01-18 21:23:48 【问题描述】:

我正在编写一个 excel 类,我想自动释放这个非托管对象。 我正在使用 IDisposable 模式并编写 Dispose 方法。 例子;

class MSExcel : IDisposable

    ApplicationClass excel;
    bool disposed;

    public MSExcel()
    
         disposed = false;
         excel = new ApplicationClass();
    

    public void Dispose(bool disposing)
    
        if (!this.disposed)
        

            if (disposing)
            

            

            excel.Quit();                
            disposed = true;

        
    

    public void Dispose()
    
        Dispose(true);
        GC.SuppressFinalize(this);
    

    ~MSExcel()
    
       Dispose(false);
    

但我在 exc.Quit() 上有经典错误。 “已与其基础 RCW 分离的 COM 对象”。 我的代码有什么错误吗?

【问题讨论】:

"Dispose" 用于释放对象,但您将其用于应用程序逻辑,即退出 Excel。将您的退出方法移到别处,不要依赖 Dispose 为您退出 Excel,您应该自己完成。 【参考方案1】:

正如我对您的其他相关问题here 的回答中所解释的,您不应该在终结器中对引用类型执行操作。正如您所做的那样,您可以通过使用Disposed(bool) 方法的bool disposing 参数来强制执行此操作。当从 void Dispose() 方法显式调用 Disposed(bool) 时传入 true,并在从终结器调用时传入 false,这也是你所做的。

但是,您还需要保护对excel.Quit() 的调用,以便在通过终结器调用Disposed(bool)调用它。也就是说,你应该只在bool disposing 参数是true 时调用excel.Quit()

因此,Disposed(bool) 方法的代码应如下所示:

public void Dispose(bool disposing)

    if (!this.disposed)
    

        if (disposing)
        
            excel.Quit();   
        

        disposed = true;
    

完成后,您可以按如下方式使用“MSExcel”类:

using (MSExcel msExcel = new MSExcel)

   // The code calling your 'MSExcel' object goes here.

通过这种方式,当您的代码到达 using statement 块的右括号“”时,将自动调用“MSExcel”类上的 Dispose 方法,确保调用 excel.Quit()确定性地,而不是来自终结器。

希望这会有所帮助...

迈克

【讨论】:

假设正在处理 Excel.Application 类的 Quit 方法,为第一个参数 (SaveChanges) 提供 True 值可防止在关闭过程中出现挂起的更改时可能挂起。当 Excel.Application 的 Visible 属性设置为 False 时,这应该是一个主要问题,这主要发生在自动化过程中。

以上是关于如何使用 IDisposeable 接口释放 excel 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何释放接口对象 (Delphi 7)

beam189端点自由度释放的实现

如图,这两个slot接口是用来插啥的?一个1一个4

接口测试-mock实例

局部变量可能指向释放的内存

天龙八部安装不了