【问题标题】:Quit excel instance as class member on demand按需退出excel实例作为班级成员
【发布时间】: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 实例就会正确退出。但我对班级不满意。当然,我想拥有myxlAppmyxlWB 的私有变量。但是如果我把我的班级改成

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


【解决方案1】:

我假设由于您在 GC.Collect 之前仍然有对 xlsInst 的引用,并且该对象包含对 excel 的引用,因此 GC 不会收集。尝试在 Collect 之前执行 xlsInst = Nothing,也可以将类中的变量设置为空。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim xlsInst As New ExcelInst
    xlsInst = Nothing
    GC.Collect()
    GC.WaitForPendingFinalizers()
End Sub End Class

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()

        myxlApp = Nothing
        myxlWb = Nothing
    End Sub
End Class

我必须补充一点,我觉得在 New() 中包含该逻辑很奇怪。我建议把它放在一个静态函数中,或者有一个 .ProcessExcel() 或 .CloseExcel() 之类的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2012-01-15
    • 2014-11-19
    • 1970-01-01
    相关资源
    最近更新 更多