Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.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#.net Excel互操作使Excel进程挂起_C#_Excel_Interop - Fatal编程技术网

C#.net 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

我们在代码中的许多地方都使用Excel interop,但是我有一个函数似乎从未关闭它使用的Excel进程。。我已经简化了代码,似乎每当我在这个函数中打开工作簿时,它都会挂起。我已经包括了下面的代码,我已经确保每个对象都已定义、发布和为空,而Excel仍在运行

        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,尽管这听起来毫无意义,但可能值得一试。