gpt4 book ai didi

.net - 使用 IDisposable 清理 Excel Interop 对象

转载 作者:行者123 更新时间:2023-11-30 18:28:12 25 4
gpt4 key购买 nike

在我公司,发布 Excel Interop 对象的常用方法是按以下方式使用 IDisposable:

Public Sub Dispose() Implements IDisposable.Dispose
If Not bolDisposed Then
Finalize()
System.GC.SuppressFinalize(Me)
End If
End Sub

Protected Overrides Sub Finalize()
_xlApp = Nothing
bolDisposed = True
MyBase.Finalize()
End Sub

_xlApp 是在构造函数中按以下方式创建的:

Try
_xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
Catch e As Exception
_xlApp = CType(CreateObject("Excel.Application"), Excel.Application)
End Try

并且客户端使用using-statement来执行与excel互操作对象有关的代码。

我们完全避免使用 two dot rule .现在我开始研究如何发布 (Excel) 互操作对象以及我发现的几乎所有关于它的讨论,如 How to properly clean up excel interop objectsRelease Excel Objects主要使用 Marshal.ReleaseComObject(),没有一个使用 IDisposable 接口(interface)。

我的问题是:使用 IDisposable 接口(interface)释放 excel 互操作对象有什么缺点吗?如果是这样,这些缺点是什么。

最佳答案

Are there any disadvantages using the IDisposable Interace

当然,它什么也做不了。使用 Using 或调用 Dispose() 永远不是将变量设置为 Nothing 的合适方法。这就是您的代码所做的全部。

We completely avoid to use the two dot rule.

请继续忽略它,这是无稽之谈,只会引起悲伤。博客作者的隐含断言是,这样做会迫使程序员使用变量来存储 xlApp.Workbooks 的值。所以他以后有机会不要忘记调用 releaseObject()。但是还有更多的语句生成不使用点的接口(interface)引用。类似于 Range(x,y),那里有一个您永远看不到的隐藏 Range 对象引用。还必须存储它们只会产生令人难以置信的复杂代码。

而只忽略一个就足以完全无法完成工作。完全无法调试。这是 C 程序员必须编写的代码。并且经常惨败,大型 C 程序经常泄漏内存,而他们的程序员花费大量时间来寻找这些泄漏。当然不是 .NET 方式,它有一个垃圾收集器来自动执行此操作。它永远不会出错。

问题是,它处理工作的速度有点慢。非常设计。没有人注意到这一点,除了在这种代码中。您可以看到垃圾收集器没有运行,您仍然看到 Office 程序在运行。当您编写 xlapp.Quit() 时它并没有退出,它仍然存在于任务管理器的进程选项卡中。他们想要的是当他们这样说时它就退出。

这在 .NET 中很有可能,您当然可以强制 GC 完成工作:

GC.Collect()
GC.WaitForPendingFinalizers()

繁荣,每个 Excel 对象引用都会自动释放。无需自己存储这些对象引用并显式调用 Marshal.ReleaseComObject(),CLR 会为您完成。而且它永远不会出错,它不使用或不需要“双点规则”,并且可以毫不费力地找到那些隐藏的接口(interface)引用。


然而,最重要的是确切地放置此代码的位置。大多数程序员将其放在错误的位置,使用的方法与使用那些 Excel 界面的方法相同。这很好,但在调试代码时不起作用,这是一个在 this answer 中解释的怪癖。 .在博客作者的代码中,正确的做法是将代码移到一个小的辅助方法中,我们称它为 DoExcelThing()。像这样:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
DoExcelThing()
GC.Collect()
GC.WaitForPendingFinalizers()
'' Excel.exe no longer running anymore at this point
End Sub

请记住,这真的只是一个调试工件。程序员只是讨厌必须使用任务管理器来杀死僵尸 Excel.exe 实例。当他们停止调试器时僵尸化,阻止程序正常退出并收集垃圾。这是正常。当您的程序出于任何原因在生产中死亡时,也会发生这种情况。把你的精力用在它所属的地方,把错误从你的代码中移除,这样你的程序就不会死掉。 GC 不需要比这更多的帮助。

关于.net - 使用 IDisposable 清理 Excel Interop 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25433418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com