问题:
我想就Mike Rosenblum的回答对这个问题提出一个问题。这个问题是关于清理Excel互操作对象的。有几种解决方案被提出(例如:包装器、不使用超过一个点、杀死Excel进程),但我最喜欢Mike Rosenblum的解决方案(关于这个主题的冗长文章)。
基本上,它的意思是你不需要过于担心所有的引用。只需保留一些主要的引用(如ApplicationClass
、Workbook
和Worksheet
)。首先调用垃圾回收来清理所有浮动的对象,然后通过调用Marshal.FinalReleaseComObject
(按重要性的相反顺序)明确清理您仍然具有的主要引用。现在我有两个问题。
第一个:我如何确定需要保留引用的对象?在Mike Rosenblum's example中,他只保留了
Ranges
、Worksheets
、Workbooks
和ApplicationClasses
。第二个:如果有更多的对象,我如何确定清理它们的顺序(即“重要性顺序”)?
更新1:
MattC
建议,在排序方面,唯一重要的是应用程序最后发布。尽管在我的参考资料中,以下句子:“您还应按重要性的相反顺序发布已命名的引用:首先是范围对象,然后是工作表、工作簿,最后是Excel应用程序对象。”暗示了有更多的排序。
null
,然后进行垃圾回收即可,但这似乎与Mike Rosenblum的文章中的以下引用相矛盾:“你会认为,你可以将所有变量设置为Nothing
,然后在最后调用GC.Collect()
,有时确实可以。然而,Microsoft Office应用程序对释放对象的顺序很敏感,不幸的是,将变量设置为Nothing
,然后调用GC.Collect()
并不能保证对象释放的顺序。”
一些额外的信息:
在我的应用程序中,我使用图表进行了很多操作。我设置了很多属性等等。据我所知,有许多地方我创建了新的COM对象。我尝试确保从不使用双点,并在我完成使用的所有对象上调用Marshal.FinalReleaseComObject
。我没有使用包装器方法,因为它会引入很多嵌套。
当我的应用程序完成工作后,EXCEL.exe
没有关闭。但是...当我告诉我的应用程序再次执行相同的工作时,它确实关闭了。当然,打开了一个新的EXCEL.exe
,它没有关闭。现在我已经删除了所有的Marshal.FinalReleaseComObject
调用,应用程序的工作完全相同。 EXCEL.exe
会一直存在,直到我告诉我的应用程序重新执行该工作,但是这时会启动并保持一个新的EXCEL.exe
。
编辑:当我告诉我的应用程序执行其他非COM相关的工作时,过一段时间EXCEL.exe
就消失了,但是现在没有新的EXCEL.exe
出现。
不确定我可以从中得出什么结论...