使用C#进行Excel开发时,使用代理模式后造成Excel的对象释放不掉的问题,代码如下:
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进程退出,但是使用下面的代码不能:
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啊?
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进程退出,但是使用下面的代码不能:
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啊?
// 杀掉进程
public static void KillProcess(string processName)
{
System.Diagnostics.Process myproc = new System.Diagnostics.Process();
//得到所有打开的进程
try
{
foreach (Process thisproc in Process.GetProcessesByName(processName))
{
if (!thisproc.CloseMainWindow())
{
thisproc.Kill();
}
}
}
catch (Exception ex)
{
//throw new Exception("", Exc);
Common.DisplayMsg("系统错误", ex.Message);
}
}
调用方法:Common.KillProcess("Excel");
但是加了一个代理的WorkBook类后,类里面声明了private Microsoft.Office.Interop.Excel.Workbook workBook;私有变量,并且在实例化代理类时传入了Excel的_workBook对象,导致在ExcelHelper类清理Excel时,无法清理所有的Excel资源,导致Excel进程无法退出!
如果这种代理模式使用在Winform程序下,当Winform进程退出时,系统清理掉了代理WorkBook类的资源,此时Excle进程随着Winform进程一起退出,也就是说下面的代码在使用完Excel后进程不会马上退出,一定要等到Winform进程退出时Excel才会一起退出!
所以我想问清楚:怎么样能在使用完Excel资源后,主动清理上面的代码里面用到的所有Excel资源?只要资源能清理干净,Excel进程可以正常退出!
我在操作PPT中chart里面的Excel表格时候,时不时会抛远程COM不可控这样的异常,
然后就中断,这时候Excel和PowerPoint进程就不能释放,之后的所有操作全都抛异常
必须杀掉这2个进程才行
怀疑是Office组件互相调用间的漏洞
...
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