当前位置: 代码迷 >> VBA >> C#使用Microsoft.Office.Interop.Excel操作后Excel对象的释放有关问题
  详细解决方案

C#使用Microsoft.Office.Interop.Excel操作后Excel对象的释放有关问题

热度:6042   发布时间:2013-02-26 00:00:00.0
C#使用Microsoft.Office.Interop.Excel操作后Excel对象的释放问题
使用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方法中
  相关解决方案