本文介绍了为什么这段代码导致Excel无法正常关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  Excel.Range范围=(Excel.Range)ws .Cells [1,1]; 

如果是因为转换,那么这段代码是不会导致同样的问题? >

  Excel.Worksheet ws =(Excel.Worksheet)wb.ActiveSheet; 

我试过了但这是有效的。 Excel将关闭。



如果我使用此代码。 Excel关闭。

  Excel.Range范围= ws.get_Range(A1,A1); 

那有什么区别?是的,我知道有一百万如何正确关闭Excel线程。但是,由于这是一个问题而不是答案,所以我决定问一个新的问题,而不是问其他人的问题。



这是我的代码。但是当然还有另外一个代码。我只是评论一切,慢慢地尝试哪些行导致Excel不关闭。我意识到即使没有使用垃圾收集器,Excel仍然关闭。我不想用大锤关闭Excel。



谢谢。

  Excel.Application objExcel = new Excel.Application(); 
Excel.Workbooks wbs = objExcel.Workbooks;
Excel.Workbook wb = wbs.Open(saveFileDialog1.FileName,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type分类,分类,分类,分类,
Excel.Worksheet ws =(Excel.Worksheet)wb.ActiveSheet;
//Excel.Range range =(Excel.Range)ws.Cells [1,1];
Excel.Range范围= ws.get_Range(A1,A1);

FinalReleaseAnyComObject(range);
FinalReleaseAnyComObject(ws);
wb.Close(Type.Missing,Type.Missing,Type.Missing);
FinalReleaseAnyComObject(wb);
FinalReleaseAnyComObject(wbs);
objExcel.Quit();
FinalReleaseAnyComObject(objExcel);

目前我已经尝试过objExcel,wbs,wb和ws。这4个对象不会引起问题。

  private static void FinalReleaseAnyComObject(object o)
{
Marshal.FinalReleaseComObject(O);
o = null;
}

我意识到您不能重复使用该变量。

  Excel.Range range = ws.get_Range(A1,G1); 
range = ws.get_Range(A1,A1);

这将导致Excel不能正确关闭。而是使用这个。

  Excel.Range range = ws.get_Range(A1,G1); 
FinalReleaseAnyComObject(range);
range = ws.get_Range(A1,A1);


解决方案

有一个隐藏的Range接口指针,你不能看到,Cells属性返回它。然后,将该索引器表达式应用于该索引器表达式,取消引用该范围的默认Item属性。要获得另一个范围。



这就是为什么尝试自己管理COM接口指针是一个糟糕的坏主意。相信垃圾收集器始终正确。 GC.Collect()和GC.WaitForPendingFinalizers()如果你真的,真的想让它按需退出。请务必阅读,以了解为什么在调试程序时并不总是按预期方式工作。


Why does this line of code cause Excel not to exit?

Excel.Range range = (Excel.Range)ws.Cells[1,1];

If it's because of the casting, then wouldn't this code cause the same problem?

Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;

I've tried. But this works. Excel will close.

If I use this code. Excel closes.

Excel.Range range = ws.get_Range("A1","A1");

So what's the difference? Yes I know there's like a million of "How to close Excel properly" threads. But since this is a question and not an answer, I decided to ask a new one instead of asking in other people's question.

Here's my code. But of course there's another codes in between. I'm just commenting out everything and slowly trying out which lines causes Excel to not close. I realise that even without using Garbage collector, Excel still closes. I do not want to use a sledgehammer to close Excel.

Thanks.

Excel.Application objExcel = new Excel.Application();
Excel.Workbooks wbs = objExcel.Workbooks;
Excel.Workbook wb = wbs.Open(saveFileDialog1.FileName, Type.Missing,  Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;
//Excel.Range range = (Excel.Range)ws.Cells[1,1];
Excel.Range range = ws.get_Range("A1","A1");

FinalReleaseAnyComObject(range);
FinalReleaseAnyComObject(ws);
wb.Close(Type.Missing, Type.Missing, Type.Missing);
FinalReleaseAnyComObject(wb);
FinalReleaseAnyComObject(wbs);
objExcel.Quit();
FinalReleaseAnyComObject(objExcel);

Currently I've tried until objExcel, wbs, wb and ws. These 4 objects does not cause a problem.

private static void FinalReleaseAnyComObject(object o)
{
    Marshal.FinalReleaseComObject(o);
    o = null;
}

I realise that you cannot reuse the variable as well.

Excel.Range range = ws.get_Range("A1","G1");
range = ws.get_Range("A1", "A1");

This will cause Excel not to close properly too. Instead, use this.

Excel.Range range = ws.get_Range("A1","G1");
FinalReleaseAnyComObject(range);
range = ws.get_Range("A1", "A1");
解决方案

There's a hidden Range interface pointer that you can't see, the Cells property returns it. You then apply the indexer expression to it, dereferencing the default Item property of that Range. To get another Range.

This is why it is such a bad, bad idea to try to manage COM interface pointers yourself. Trust the garbage collector to always get it right. GC.Collect() and GC.WaitForPendingFinalizers() if you really, really want to make it quit on demand. Be sure to read this answer to understand why this doesn't always work as expected when you debug your program.

这篇关于为什么这段代码导致Excel无法正常关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 13:53
查看更多