使用Wrapper对象来正确清理Excel互操作对象
所有这些问题:
与使用它们之后C#不能正确释放Excel COM对象的问题斗争。 围绕这个问题主要有两个方向:
有些人表示2太繁琐,你是否忘记在代码中的某些地方忘记遵守这条规则总会有一些不确定性。 仍然1似乎肮脏和容易出错,我想,在一个限制环境试图杀死一个进程可能会引发安全错误。
所以我一直在想通过创建另一个模仿Excel对象模型的代理对象模型来解决问题2(对于我来说,实现我实际需要的对象就足够了)。 原则如下:
例:
public class Application
{
private Microsoft.Office.Interop.Excel.Application innerApplication
= new Microsoft.Office.Interop.Excel.Application innerApplication();
~Application()
{
Marshal.ReleaseCOMObject(innerApplication);
innerApplication = null;
}
public Workbooks Workbooks
{
get { return new Workbooks(innerApplication.Workbooks); }
}
}
public class Workbooks
{
private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;
Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
{
this.innerWorkbooks = innerWorkbooks;
}
~Workbooks()
{
Marshal.ReleaseCOMObject(innerWorkbooks);
innerWorkbooks = null;
}
}
我对你的问题特别是:
在析构函数中执行ReleaseCOMObject是不可能/不好/危险的吗? (我只看到了将它放入Dispose()而不是析构函数的建议 - 为什么?)
建议不要将清理后的代码放入终结器中,因为与C ++中的析构函数不同,它不会被确定性地调用。 它可能会在对象超出范围后立即调用。 这可能需要一个小时。 它可能永远不会被调用。 一般来说,如果你想处置非托管对象,你应该使用IDisposable模式而不是终结器。
您链接的此解决方案试图通过显式调用垃圾回收器并等待终结器完成来解决该问题。 这通常不被推荐,但对于这种特殊情况,有些人认为这是一个可接受的解决方案,因为难以跟踪所有创建的临时非托管对象。 但明确清理是正确的做法。 然而鉴于这样做的困难,这种“黑客”可能是可以接受的。 请注意,此解决方案可能比您提出的想法更好。
相反,如果您想要明确清理,“不要在COM对象中使用两个点”指南将帮助您记住为每个创建的对象保留一个引用,以便在完成后清理它们。
我们使用MSDN杂志中描述的LifetimeScope类。 使用它可以很好地清理对象,并且可以很好地处理我们的Excel导出。 代码可以在这里下载,也包含杂志文章:
http://lifetimescope.codeplex.com/SourceControl/changeset/changes/1266
看看我的项目MS Office for .NET。 通过本机VB.NET后期绑定功能解决了referencich包装对象和本地对象的问题。
链接地址: http://www.djcxy.com/p/35647.html上一篇: Using Wrapper objects to Properly clean up excel interop objects