我在C#(ApplicationClass)中使用Excel互操作,并在我的finally子句中放置了以下代码:
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet) != 0) { }
excelSheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)
虽然这种工作,Excel.exe即使我关闭Excel后,该过程仍然在后台.只有在我的应用程序手动关闭后才会发布.
我做错了什么,或者是否有其他方法可以确保互操作对象得到妥善处理?
COM对象通常具有确定性破坏:在释放最后一个引用时释放它们.
如何处理C# - COM Interop?这些类没有实现IDisposable,所以我认为无法触发显式的IUnknown :: Release.
随意测试显示未引用的COM对象被懒惰地收集(即垃圾收集器触发释放).对于需要被激活释放的OCM对象,我该怎么办?(例如持有大型或共享的关键资源)?
原始问题:我们有一个C#应用程序大量使用COM库,它像疯了一样泄漏.似乎问题是"在C++和C#代码之间"(我们可以访问它们),但我们无法确定它.
在使用Excel Interop与.Net开发一段时间之后,我越来越恼火于发生了多少"奇怪的事情" - 比如我之前发布的这个问题 - 我的问题.
我理解这不是一个直接的问题,更多的是经验的结合,但我确实认为找出人们最大的烦恼/奇怪的事情以及如何克服它们会有所帮助.
这样我就可以找出将来遇到的问题:)
谢谢
如何从正在运行的对象中获取进程ID?
Dim xlApp As Object = CreateObject("Excel.Application")
Run Code Online (Sandbox Code Playgroud)
我需要使用后期绑定,因为我无法保证我将获得哪个版本,因此使用Microsoft.Office.Interop.Excel将无法正常工作.
'do some work with xlApp
xlApp.Quit
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
xlApp = nothing
Run Code Online (Sandbox Code Playgroud)
此时Excel仍在后台运行.我熟悉使用变量的所有建议并释放它们然后使用:System.Runtime.InteropServices.Marshal.ReleaseComObject(o).这不能可靠地工作.我正在做的工作非常复杂.我使用多个文件用于每个循环等.无法在Excel中释放所有资源.我需要一个更好的选择.
我想Process.Kill在Excel 上使用,但我不知道如何从xlApp对象获取进程.我不想杀死所有Excel进程,因为用户可能打开了工作簿.
我尝试使用Dim xProc As Process = Process.Start(ExcelPath)然后使用xProc.Kill()有时工作除了使用XLApp = GetObject("Book1").Application或XLApp = GetObject("", "Excel.Application")如果用户已经打开Excel窗口使用正确的Excel对象有点棘手.我需要一个更好的选择.
我不能使用GetActiveObject或BindToMoniker获取Excel对象,因为它们仅在使用早期绑定时才能工作.例如Microsoft.Office.Interop.Excel
如何从正在运行的对象中获取进程ID?
编辑:其实我真的不想对如何让Excel很好地退出进行重新考虑.许多其他问题都解决了这个问题 在这里和这里我只想杀死它; 干净,准确,直接.我想要杀死我开始的确切过程而不是其他过程.