Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 挂起互操作COM对象时出现问题_C#_Excel_Com_Interop - Fatal编程技术网

C# 挂起互操作COM对象时出现问题

C# 挂起互操作COM对象时出现问题,c#,excel,com,interop,C#,Excel,Com,Interop,我有一个应用程序,它使用COM互操作创建一个电子表格,该电子表格在客户机的Excel中打开。但是,如果我查看Task Manager,当用户关闭EXCEL时,EXCEL.exe进程似乎并不总是结束 如果我保存工作簿并以编程方式关闭Excel,我只会使用Marshal.ReleaseComObject()进行清理,但由于我依赖于手动关闭程序,因此我不确定该怎么做。有什么建议吗?可能Excel.exe仍处于打开状态,因为用户在Excel应用程序的同一实例中打开了另一个文档。在这种情况下,您可能不应该

我有一个应用程序,它使用COM互操作创建一个电子表格,该电子表格在客户机的Excel中打开。但是,如果我查看Task Manager,当用户关闭EXCEL时,EXCEL.exe进程似乎并不总是结束


如果我保存工作簿并以编程方式关闭Excel,我只会使用
Marshal.ReleaseComObject()
进行清理,但由于我依赖于手动关闭程序,因此我不确定该怎么做。有什么建议吗?

可能Excel.exe仍处于打开状态,因为用户在Excel应用程序的同一实例中打开了另一个文档。在这种情况下,您可能不应该终止Excel.exe进程


如果您确保关闭所有打开的文档,并释放所有创建的对象,那么为什么确保Excel.exe终止对您很重要?可能该进程正在为另一个应用程序或用户服务?

可能有很多原因(包括Ran),但我在MapPoint(另一个具有COM接口的Microsoft应用程序)中经常看到的一个原因是,您必须确保清除所有对象引用,以便垃圾收集器可以清除它们。一个较低的对象挂起就足以阻止应用程序关闭并退出进程列表。

Excel在其所有进程外对象释放之前无法终止。所以它只是隐藏了它的用户界面并继续运行。直到程序退出或将所有Excel对象引用设为空,并且终结器线程运行。退出你的计划将是一个显而易见的解决办法。或者,您可以强制终结器线程以以下方式运行:

GC.Collect();
GC.WaitForPendingFinalizers();

ReleaseComObject()很少工作,因为很容易忘记中间COM对象引用。就像工作簿[索引]一样,这是一个你看不到的枚举器。让GC自己做出决定将是更明智的选择,如果您继续运行和工作,那么这将发生。

如果我使用以下命令打开Excel应用程序和工作簿:

Excel.Application app = new Excel.Application();
Excel.Workbook wb = app.Workbooks.Open(...);

然后在finally语句(或其他适当的关闭事件)中使用
wb.Close()
app.Quit()
方法。这将清理Exel.exe进程。无需调用
Marshall.ReleaseComObject
或GC方法。

删除这些对象引用的最佳方法是什么?我应该使用
ReleaseComObject()
?看起来Hans已经回答了。将引用设置为null。如果这还不够,请在完成时运行GC.Collect。NET通常能很好地处理COM(就像旧的VB6),您不需要太多地担心底层细节。
GC.Collect()
GC.WaitForPendingFinalizers()
似乎可以做到这一点。