使用C#进行Excel开发时,使用代理模式后造成Excel的对象释放不掉的问题,代码如下:
- C# code
public class ExcelHelper : IDisposable { public ExcelHelper() { this._application = new myExcel.Application(); this._application.Visible = false; this._workbooks = this._application.Workbooks; } public Microsoft.Office.Interop.Excel.Workbook Open(string filePath) { this._workbooks.Open(filePath); } }
上面的代码使用
using(ExcelHelper excel=new ExcelHelper)
{},可以正常释放所有Excel对象并将Excel进程退出,但是使用下面的代码不能:
- C# code
public partial class ExcelHelper : IDisposable { public ExcelHelper() { this._application = new comExcel.Application(); this._application.Visible = false; this._application.DisplayAlerts = false; this._application.AlertBeforeOverwriting = false; this._workbooks = this._application.Workbooks; } public WorkBook CreateWorkBook(string filePath) { return new WorkBook(this._workBooks.Open(filePath)); } } public class WorkBook { private Microsoft.Office.Interop.Excel.Workbook workBook; internal readonly object missing = System.Reflection.Missing.Value; private WorkBook() { } internal WorkBook(Microsoft.Office.Interop.Excel.Workbook _workBook) { this.workBook = _workBook; } }
上面的代码使用
using(ExcelHelper excel=new ExcelHelper)
{}
后,WorkBook类里面的私有成员private Microsoft.Office.Interop.Excel.Workbook workBook好像不能释放,导致Excel进程无法退出,这里该如何释放所有成员并正常退出Excel啊?
------解决方案--------------------------------------------------------
Google到的
Excel does not quit because your app is still holding references to COM objects.
I guess you're invoking members of a COM object without assigning it to a variable.
For me it was the excelApp.Worksheets object I directly used without assigning it to a variable:
Worksheet sheet = excelApp.Worksheets.Open(...);
...
Marshal.ReleaseComObject(sheet);
What I didn't know was that internally C# created a wrapper for the Worksheets COM object which didn't get released by my code (because I wasn't aware of it) and was the cause why Excel was not unloaded.
I found the solution to my problem on this page, which also has a nice rule for the usage of COM objects in C#:
Never use 2 dots with com objects.
So with this knowledge the right way of doing the above is:
Worksheets sheets = excelApp.Worksheets; // <-- the important part
Worksheet sheet = sheets.Open(...);
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);
然后调用
xlBook(Workbooks类型).Close()和xlApp.Quit();
上面的资料来自:
http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c-sharp
------解决方案--------------------------------------------------------
findcaiyzh 找到的文章很给力
写在Dispose方法中