如何通过IDisposeable接口释放excel对象

发布于 2024-08-18 03:29:28 字数 729 浏览 3 评论 0原文

我正在编写一个 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() 上遇到经典错误。 “COM 对象已与其底层 RCW 分离”。 我的代码有错误吗?

I am writing an excel class and i want to release this unmanaged object automatically.
I'm using IDisposable pattern and write Dispose methods.
Example ;

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);
    }
}

But i have classical error on exc.Quit().
"COM object that has been separated from its underlying RCW".
Have any my mistake in code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月蹉跎了容颜 2024-08-25 03:29:28

正如我在此处对您的其他相关问题的回答中所解释的,您不应该在终结器中对引用类型执行操作。您可以通过使用 Dispose(bool) 方法的 bool dispose 参数来强制执行此操作,就像您所做的那样。当从 void Dispose() 方法显式调用 Dispose(bool) 时,您传入 true,并传入 false< /code> 当从终结器调用时,您也已经完成了。

但是,您还需要保护对 excel.Quit() 的调用,以便在通过调用 Dispose(bool)不会调用它终结器。也就是说,您应该仅在 bool dispose 参数为 true 时调用 excel.Quit()

因此,Dispose(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 语句的右括号“}”< /a> 块,“MSExcel”类上的 Dispose 方法将自动调用,确保确定性地调用 excel.Quit(),而不是从终结器调用。

希望这有帮助...

迈克

As explained in my answer to your other related question here, you should not be taking actions on reference types from within your finalizer. You enforce this by making use of the bool disposing parameter of your Disposed(bool) method, as you have done. You pass in true, when Disposed(bool) is called explicitly from the void Dispose() method, and pass in false when called from your finalizer, which you have also done.

However, you also need to protect your call to excel.Quit() so that it is not called when Disposed(bool) is called via the finalizer. That is, you should only call excel.Quit() when the bool disposing argument is true.

Therefore, the code for your Disposed(bool) method should look as follows:

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

        if (disposing)
        {
            excel.Quit();   
        }

        disposed = true;
    }
}

Once done, you could make use of your "MSExcel" class as follows:

using (MSExcel msExcel = new MSExcel)
{
   // The code calling your 'MSExcel' object goes here.
}

By doing it this way, when your code gets to the closing bracket, "}", of your using statement block, the Dispose method on your 'MSExcel' class will be called automatically, ensuring that excel.Quit() is called deterministically, and not from a finalizer.

Hope this helps...

Mike

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文