问题描述
我在C#( ApplicationClass
)中使用Excel interop,并将以下代码放在我的finally子句中: $ b $ while(System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet)!= 0){}
excelSheet = null; b
GC.Collect();
GC.WaitForPendingFinalizers();
尽管这种作品, Excel.exe
进程仍然处于后台,即使我关闭了Excel。一旦我的应用程序被手动关闭,它才被释放。
我做错了什么,还是有一个替代方法来确保interop对象被妥善处理?
Excel不会退出,因为您的应用程序仍然持有对COM对象的引用。
我想你正在调用一个COM对象的至少一个成员,而不分配给变量。
对我来说,这是 excelApp.Worksheets 我直接使用的对象,而不将其分配给变量:
Worksheet sheet = excelApp。 Worksheets.Open(...);
...
Marshal.ReleaseComObject(sheet);
我不知道内部的C#为工作表创建了一个包装器COM对象没有被我的代码释放(因为我没有意识到),并且是为什么没有卸载Excel的原因。
我找到了解决方案关于我在上的问题,这也是C#中使用COM对象的一个很好的规则:
所以用这个知识,正确的方法是:
工作表sheet = excelApp.Worksheets; //< - 重要的部分
工作表sheet = sheets.Open(...);
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);
I'm using the Excel interop in C# (ApplicationClass
) and have placed the following code in my finally clause:
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet) != 0) { }
excelSheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Although this kind of works, the Excel.exe
process is still in the background even after I close Excel. It is only released once my application is manually closed.
What am I doing wrong, or is there an alternative to ensure interop objects are properly disposed of?
Excel does not quit because your application is still holding references to COM objects.
I guess you're invoking at least one member of a COM object without assigning it to a variable.
For me it was the excelApp.Worksheets object which I directly used without assigning it to a variable:
Worksheet sheet = excelApp.Worksheets.Open(...);
...
Marshal.ReleaseComObject(sheet);
I didn't know that internally C# created a wrapper for the Worksheets COM object which didn't get released by my code (because I wasn't aware of it) and was the cause why Excel was not unloaded.
I found the solution to my problem on this page, which also has a nice rule for the usage of COM objects in C#:
So with this knowledge the right way of doing the above is:
Worksheets sheets = excelApp.Worksheets; // <-- The important part
Worksheet sheet = sheets.Open(...);
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);
这篇关于如何正确清理Excel互操作对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!