【发布时间】:2014-11-04 17:41:25
【问题描述】:
我尝试创建一个要使用 excel 实例的类,并且我想按需退出该 excel 实例(如this answer 中所述。为了仍然能够debug it properly 我将垃圾收集分开以下方式:
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim xlsInst As New ExcelInst
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub End Class
Public Class ExcelInst
Sub New()
Dim myxlApp As New Excel.Application
Dim myxlWb As Excel.Workbook
'~~> Add a new Workbook
myxlWb = myxlApp.Workbooks.Add
'~~> Display Excel
myxlApp.Visible = True
myxlApp.Quit()
End Sub End Class
观察任务管理器,一旦加载表单,excel 实例就会正确退出。但我对班级不满意。当然,我想拥有myxlApp 和myxlWB 的私有变量。但是如果我把我的班级改成
Public Class ExcelInst
Private myxlApp As New Excel.Application
Private myxlWb As Excel.Workbook
Sub New()
'~~> Add a new Workbook
myxlWb = myxlApp.Workbooks.Add
'~~> Display Excel
myxlApp.Visible = True
myxlApp.Quit()
End Sub
End Class
excel 不再按需关闭。有谁知道为什么第一个 sn-p 有效(根据我的要求,第二个不是?
【问题讨论】:
-
您必须调用 ReleaseComObject stackoverflow.com/questions/15697282/… 在对象的构造函数中打开和关闭 excel 似乎很奇怪。另外,在您的负载中,调用垃圾回收时 xlsInst 对象仍然存在。
-
ReleaseComObject 完全是我尽量避免的,因为不建议这样做(请参阅我的链接)。而且我不是在寻找解决方法,我只是想知道为什么第一个有效而第二个无效。我将在我的帖子中澄清这一点。
-
我假设由于您在 GC.Collect 之前仍有对 xlsInst 的引用,并且该对象包含对 excel 的引用,因此 GC 不会收集。尝试在收集之前执行 xlsInst = Nothing,也可以将类中的变量设置为空。
-
您不必调用 ReleaseComObject。只需将 myxlApp 和 myxlWb 设置为 Nothing,这样在调用 GC.Collect() 时就没有对 Excel COM 对象的引用。如果您想将 xlsInst 设置为 Nothing,您再次需要小心您提到的调试问题。
-
将 myxlApp 和 myxlWb 设置为什么都解决了我的问题。非常感谢。如果你愿意,你可以写一个简短的答案,我会确认的。
标签: .net vb.net excel garbage-collection interop