gpt4 book ai didi

vb.net - Excel 进程未在 VB.net 中关闭

转载 作者:行者123 更新时间:2023-12-01 21:47:46 27 4
gpt4 key购买 nike

我正在使用 interop.excel 创建 Excel 文件,但该进程未关闭。这是我正在尝试使用的代码。

 Private Sub converToExcel(fileLoc As String, ds As DataSet)
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkBooks As Excel.Workbooks
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer

xlApp = New Excel.Application
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkSheet = xlWorkBook.Sheets("sheet1")

For i = 0 To ds.Tables(0).Rows.Count - 1
For j = 0 To ds.Tables(0).Columns.Count - 1
xlWorkSheet.Columns.NumberFormat = "@"
xlWorkSheet.Cells(i + 1, j + 1) = String.Format("{0}", ds.Tables(0).Rows(i).Item(j).ToString())
Next
Next

xlWorkSheet.SaveAs(fileLoc)
xlWorkBook.Close()
xlApp.Quit()

releaseObject(xlWorkSheet)
releaseObject(xlWorkBook)
releaseObject(xlWorkBooks)
releaseObject(xlApp)

End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub

我认为我缺少一个 COM 对象,但似乎无法找到解决方案。另请注意,它在 64 位 Windows 8 上运行。任何帮助都会很棒!谢谢

最佳答案

像这样的手动内存管理根本行不通。这是一个很长时间以来人们都知道的问题,也是垃圾收集器被发明的核心原因。程序员只是永远忘记释放内存。

当您看不到正在使用的内存时,事情会变得格外困难。在您的代码中肯定是这种情况,xlWorkSheet.Cells(i + 1, j + 1) 表达式使用不少于三个 引用。一个用于 Cells 属性返回的范围对象,一个用于由 i+1 选择的子范围对象,另一个用于由 j+1 选择的子范围对象。 VB.NET 语言提供了非常好的语法糖,如果没有它,编写 COM 代码会非常痛苦。但对让你看到引用资料没有帮助。您不仅无法在源代码中看到它,调试器也绝对无法帮助您看到它们。

这在 .NET 中已经是一个已解决的问题,它有一个垃圾收集器,并且可以看到一切。最基本的问题是你不给它机会解决你的问题。你犯的错误是你停下来。可能是在最后一条语句上设置断点,然后查看任务管理器并看到 Excel.exe 仍在运行。是的,这很正常。垃圾收集不是即时的。

调用 GC.Collect() 应该可以使其即时完成,但这在运行项目的调试版本的特定情况下不起作用。局部变量的生命周期会延长到方法的末尾,帮助您在“自动/局部/监视”窗口中查看它们。换句话说,GC.Collect() 实际上并不收集任何接口(interface)引用。有关该行为的更多信息,请参阅 this post .

简单的解决方法是不停止。继续做有用的事情来给垃圾收集器一个运行的理由。或者让程序在完成后终止,Excel 将在终结器线程最后一次运行时终止。这是有效的,因为具有引用的局部变量不再在范围内。

但无论如何,每个人都希望立即修复。您可以通过删除所有releaseObject() 调用来获得它。而是这样做:

converToExcel(path, dset)
GC.Collect()
GC.WaitForPendingFinalizers()

或者换句话说,在方法返回后强制进行集合。局部变量不再在作用域内,因此它们无法保留 Excel 引用。现在,当您调试它时,它也可以工作,就像您在没有调试器的情况下运行发布版本时一样。

关于vb.net - Excel 进程未在 VB.net 中关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14222501/

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