问题:
我想问一个问题以回应Mike Rosenblum对这个问题的回答。问题是关于清理 Excel 互操作对象。建议的几种解决方案(例如,包装器,不使用多个点,终止 excel 进程),但我最喜欢Mike Rosenblum对这个问题的解决方案(关于该主题的冗长文章)。
它基本上说的是您不必太担心所有浮动的参考。你只保留一些主要的(比如ApplicationClass
,Workbook
和Worksheet
)。您首先调用垃圾收集来清理所有浮动的对象,然后通过调用显式清理您仍然拥有的主要引用Marshal.FinalReleaseComObject
(按重要性相反的顺序)。
现在我有两个问题。
第一:我如何确定我需要保留哪些对象的引用?在Mike Rosenblum 的示例中,他只保留Ranges
,和.
第二:如果有更多的对象,我如何确定清理它们的顺序(即“重要性顺序”)?Worksheets
Workbooks
ApplicationClasses
提前致谢。
更新1:
有人建议MattC
,对于订单,唯一重要的是应用程序最后发布。尽管在我的参考资料中有以下句子:“您还应该按重要性相反的顺序释放您的命名参考资料:首先是范围对象,然后是工作表、工作簿,最后是您的 Excel 应用程序对象。” 意味着有更多的排序。
nobugz
建议将所有内容设置为null
然后进行垃圾收集就足够了,但这似乎与Mike Rosenblum 文章中的以下引用相矛盾:“你会认为,你可以设置所有变量 =Nothing
然后GC.Collect()
在最后调用,这有时确实有效。但是,Microsoft Office 应用程序对释放对象的顺序很敏感,不幸的是,设置变量 =Nothing
然后调用GC.Collect()
并不能保证对象的释放顺序。
更新 2:
一些额外的信息:在我自己的应用程序中,我用图表做了很多事情。我正在设置很多属性等。据我所知,有很多地方可以创建新的 COM 对象。我试图确保我从不使用双点,并且我试图调用Marshal.FinalReleaseComObject
我完成的所有对象。我没有使用包装方法,因为它会引入大量嵌套。
EXCEL.exe
我的应用程序完成工作后没有关闭。但是......当我告诉我的应用程序再次执行相同的工作时,它确实关闭了。当然是新EXCEL.exe
开的没有关门的。现在我已经删除了所有Marshal.FinalReleaseComObject
调用,并且应用程序的工作方式完全相同。EXCEL.exe
停留,直到我告诉我的应用程序重做工作,但随后一个新的开始EXCEL.exe
并停留。
编辑:另外,当我告诉我的应用程序做其他非 COM 相关的工作时,一段时间后EXCEL.exe
消失了,但现在没有新的EXCEL.exe
出现。
不知道我能从中得出什么结论......