C#.net Excel互操作使Excel进程挂起
我们在代码中的许多地方都使用Excel interop,但是我有一个函数似乎从未关闭它使用的Excel进程。。我已经简化了代码,似乎每当我在这个函数中打开工作簿时,它都会挂起。我已经包括了下面的代码,我已经确保每个对象都已定义、发布和为空,而Excel仍在运行C#.net Excel互操作使Excel进程挂起,c#,excel,interop,C#,Excel,Interop,我们在代码中的许多地方都使用Excel interop,但是我有一个函数似乎从未关闭它使用的Excel进程。。我已经简化了代码,似乎每当我在这个函数中打开工作簿时,它都会挂起。我已经包括了下面的代码,我已经确保每个对象都已定义、发布和为空,而Excel仍在运行 System.Data.DataTable dtExcelSheet = new System.Data.DataTable(); Microsoft.Office.Interop.Excel.Applic
System.Data.DataTable dtExcelSheet = new System.Data.DataTable();
Microsoft.Office.Interop.Excel.Application excelObject = new Microsoft.Office.Interop.Excel.Application();
dtExcelSheet.Columns.Add("SheetName", typeof(string));
dtExcelSheet.Columns["SheetName"].ReadOnly = false;
dtExcelSheet.Columns["SheetName"].Caption = "Sheet Name";
Workbooks wbs = excelObject.Workbooks;
Workbook excelWorkbook = wbs.Add(excelFile);
excelWorkbook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
wbs.Close();
excelObject.Quit();
int i1 = Marshal.FinalReleaseComObject(excelWorkbook);
int i2 = Marshal.FinalReleaseComObject(wbs);
int i3 = Marshal.FinalReleaseComObject(excelObject);
excelWorkbook = null;
wbs = null;
excelObject = null;
GC.GetTotalMemory(false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.GetTotalMemory(true);
确保您不是在后台线程上调用Excel。我有一个类似的问题,我正在清理所有的COM对象,但Excel仍然没有消亡,这就是问题所在
我写下了我的经验和解决方案。确保你不是在后台线程中调用Excel。我有一个类似的问题,我正在清理所有的COM对象,但Excel仍然没有消亡,这就是问题所在
我写下了我的经历和解决方案。完全猜测,但这一行:
dtExcelSheet.Columns.Add("SheetName", typeof(string));
是否返回已创建的列
如果是这样,您可能需要存储该引用,并在最后清理它
编辑:另外,我不认为您应该在最后将变量设置为null,我认为这只是再次访问它们
您不必告诉GC收集etc,但我假设这可能是您的测试代码。完成猜测,但这一行:
dtExcelSheet.Columns.Add("SheetName", typeof(string));
是否返回已创建的列
如果是这样,您可能需要存储该引用,并在最后清理它
编辑:另外,我不认为您应该在最后将变量设置为null,我认为这只是再次访问它们
您不必告诉GC收集etc,但我想这可能是您的测试代码。我已经有一段时间没有处理过这些东西了,所以没有任何东西会对我产生影响
在这些情况下,我通常建议将excel应用程序对象设置为
Visible=true
,以查看是否没有弹出对话框。Excel/Word有时会拒绝关闭,如果他们认为有一个模式对话框处于打开状态,不管你做什么。不管怎样,这是第一件要检查的事情。我已经有一段时间没有在这件事上乱搞了,所以没有什么东西会对我产生影响
在这些情况下,我通常建议将excel应用程序对象设置为
Visible=true
,以查看是否没有弹出对话框。Excel/Word有时会拒绝关闭,如果他们认为有一个模式对话框处于打开状态,不管你做什么。无论如何,这是检查的第一件事。我尝试运行您的代码,但无法重现该问题。如果我使用调试器单步执行,Excel进程将在最后一次调用finalEleaseComObject
后终止。罪魁祸首是否可能存在于清单中不存在的某些代码中
在使用COM互操作时,我发现以非常微妙的方式增加COM对象上的引用计数非常容易。例如,假设您执行以下操作:
excelWorkbook.Foo.Bar();
Foo foo = excelWorkbook.Foo;
foo.Bar();
Marshal.ReleaseComObject(foo);
这可能会增加Foo
对象上的引用计数,使您以后无法释放它……并使Excel进程在您关闭应用程序之前一直徘徊。您可以像这样重新编写上述代码行:
excelWorkbook.Foo.Bar();
Foo foo = excelWorkbook.Foo;
foo.Bar();
Marshal.ReleaseComObject(foo);
它没有那么漂亮,但在您使用完
Foo
对象后,它会减少该对象上的引用计数。我尝试运行您的代码,但无法重现该问题。如果我使用调试器单步执行,Excel进程将在最后一次调用finalEleaseComObject
后终止。罪魁祸首是否可能存在于清单中不存在的某些代码中
在使用COM互操作时,我发现以非常微妙的方式增加COM对象上的引用计数非常容易。例如,假设您执行以下操作:
excelWorkbook.Foo.Bar();
Foo foo = excelWorkbook.Foo;
foo.Bar();
Marshal.ReleaseComObject(foo);
这可能会增加Foo
对象上的引用计数,使您以后无法释放它……并使Excel进程在您关闭应用程序之前一直徘徊。您可以像这样重新编写上述代码行:
excelWorkbook.Foo.Bar();
Foo foo = excelWorkbook.Foo;
foo.Bar();
Marshal.ReleaseComObject(foo);
虽然没有那么漂亮,但在您使用完
Foo
对象后,它会减少该对象上的引用计数。前几天我也遇到过同样的情况。请参阅我关于修复的问题(问题主要涉及多行删除,但我也有同样的问题,因为您发现它与正确释放所有COM对象有关)。前几天我也遇到了同样的问题。请参阅我关于修复的问题(该问题主要涉及多行删除,但我也有相同的问题,因为您发现它与正确释放所有COM对象有关).如果发生这种情况,你只需要设置DisplayAlerts=False。如果发生这种情况,你只需要设置DisplayAlerts=False。匿名栏也是我的猜测。@Rick:你说得对,我看错了。我的答案剩下的唯一一件事就是最后不要将它们设为null,尽管这听起来毫无意义,但可能值得一试。匿名专栏也是我的猜测。@Rick:你说得对,我看错了。我的答案剩下的唯一一件事就是最后不要将它们设置为null,尽管这听起来毫无意义,但可能值得一试。