Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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
后台Excel线程未被终止C#_C#_.net_Asp.net Mvc_Excel_Background Process - Fatal编程技术网

后台Excel线程未被终止C#

后台Excel线程未被终止C#,c#,.net,asp.net-mvc,excel,background-process,C#,.net,Asp.net Mvc,Excel,Background Process,需要使用Excel互操作。我可以成功地打开并读取excel文件,但在关闭它时,该excel的后台进程不会停止。尝试使用以前SO链接中的几种解决方案,但没有成功!所以我的问题是,如何杀死后台进程 以下是我当前使用的更新代码: Excel.Application application = new Excel.Application(); var workbooks = application.Workbooks; Excel.Workbook workbook = workbooks.Open(

需要使用Excel互操作。我可以成功地打开并读取excel文件,但在关闭它时,该excel的后台进程不会停止。尝试使用以前SO链接中的几种解决方案,但没有成功!所以我的问题是,如何杀死后台进程

以下是我当前使用的更新代码

Excel.Application application = new Excel.Application();

var workbooks = application.Workbooks;
Excel.Workbook workbook = workbooks.Open(path);
Excel.Worksheet worksheet = workbook.ActiveSheet;
Excel.Range range = worksheet.UsedRange;
var rows = range.Rows;

// Some business logic  

for (int row = 2; row <= rows.Count; row++)
{
   //Read the data from the excel
}

// Some business logic

//close the excel
rows.Clear();
cell.Clear();
range.Clear();

workbook.Close(false);
application.Quit();

while (Marshal.FinalReleaseComObject(rows) != 0) { }
while (Marshal.FinalReleaseComObject(cell) != 0) { }
while (Marshal.FinalReleaseComObject(range) != 0) { }
while (Marshal.FinalReleaseComObject(worksheet) != 0) { }
while (Marshal.FinalReleaseComObject(workbook) != 0) { }
while (Marshal.FinalReleaseComObject(workbooks) != 0) { }
while (Marshal.FinalReleaseComObject(application) != 0) { }

rows = null;
cell = null;
range = null;
worksheet = null;
workbook = null;
workbooks = null;
application = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Excel.Application=new Excel.Application();
var工作簿=application.workbooks;
Excel.工作簿=工作簿.Open(路径);
Excel.Worksheet工作表=workbook.ActiveSheet;
Excel.Range=worksheet.UsedRange;
var rows=范围。行;
//一些商业逻辑

对于(int row=2;row您正在使用range.Rows.Count,这可能违反了“永远不要对com对象使用2点”规则

你可以试着包括这个

var rows = range.Rows
for (int row = 2; row <= rows.Count; row++)
{
   //Read the data from the excel
}
rows.Clear(); //rows is itself a range object 
var rows=range.rows

对于(int row=2;row我不得不使用Excel interop的几次,我在遵循以下简单规则时没有遇到任何问题:

  • 始终将任何Excel互操作包装在
    try finally
    块。在
    最后
    块中放入所有释放逻辑
  • 使用
    Marshal.FinalReleaseComObject
    释放命名COM 引用,因为它本质上是为您执行ref-count循环
  • 急切地从最深处释放COM对象到 最浅。在你的情况下,我会从
    范围开始
    ,然后是
    工作表
    然后是
    工作簿
    等等
  • 使用
    GC.Collect()
    GC.WaitForPendingFinalizers()
    正确释放未引用的COM对象(双点规则)。手动执行此操作之前 释放您持有命名引用的挂起COM对象

  • 尝试过。但没有成功:(感谢您的输入:)您尝试过吗?Marshal.ReleaseComObject(范围),Marshal.ReleaseComObject(行)是的,但仍然不起作用。甚至尝试了FinalReleaseComObject()而不是ReleaseComObject()。但仍然没有成功:(您没有释放
    范围
    。此外,如果您通过
    封送.ReleaseComObject
    手动释放RCW,
    GC.Collect
    GC.WaitForPendingFinalizers
    应该不需要。最后,使用
    封送.FinalReleaseComObject
    ,它将在一次调用中为您完成循环。此外,作为一种良好的实践,倾向于将这类代码包装在
    try finally
    块中,以确保在正常执行和可恢复的错误情况下正确释放所有COM对象。@中间:是的,代码包装在一个try catch中,我在这里发布之前和之后还有一些内容,认为它们不是必需的,因为它们只是eant对于其他一些BL实现:)@inBetween尝试了所有这些,但没有得到好的结果:(我真的很傻,错过了很小的东西吗?)感觉很笨!/这可能根本不是,只是以防万一;当我使用Excel互操作时,我倾向于将COM对象从最深的版本释放到最浅的地方。使用更多的代码时,可能您持有一些对未注意到的COM对象的引用。@IamRuku这根本不是运行时异常。似乎发生的情况是,您只是试图在应用程序发布后检查它。RCW引用计数已达到零,运行时已发布其所有引用对COM对象(
    应用程序
    )的引用。如果是这样的话,那么为什么后台进程仍然存在于任务管理器中?因为,我可以看到所有其他资源都被清理(使用VS),并且没有引发其他异常!@IamRuku我不知道,因为我看不到您的所有代码。某个地方某个对象的引用保持活动状态。您将
    application
    的引用计数正确设置为零并不意味着如果其他对象仍在引用该对象,则该对象已被释放直接或间接地。你不能再使用
    应用程序
    引用了。在我刚刚上传到GitHub的一个项目中,看看这个小东西。这是我通常处理Excel互操作的方式,我从来没有遇到过任何问题。顺便说一句,我使用的是Excel版本2007-2013。