c# – 使用Wrapper对象来正确清理excel的互操作对象
所有这些问题:
> Excel 2007 Hangs When Closing via .NET C#在使用它们后不会正确释放Excel COM对象的问题.这个问题主要有两个方向: >当Excel不再使用时,请关闭Excel进程. 有些人表示,2太乏味,总是有一些不确定性,无论你是否忘记在代码中的某些地方遵守这一规则.仍然1似乎很脏,容易出错,我也猜测在一个有限的环境下,试图杀死一个进程可能会引发安全错误. 所以我一直在想通过创建另一个模拟Excel对象模型的代理对象模型来解决问题2(对我而言,实现我实际需要的对象就足够了).原则如下: >每个Excel Interop类都有它的代理,它包装该类的对象. 例: 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; } } 我的问题特别是: 谁发现这是一个坏主意,为什么? 解决方法
建议不要将清理代码放在finalizer中,因为与C中的析构函数不同,它不是确定性地调用.在对象超出范围后不久可能会被调用.可能需要一个小时.它可能永远不会被调用.一般来说,如果要处理非托管对象,则应使用IDisposable模式,而不是终结器. 您链接的这个solution试图通过显式调用垃圾收集器并等待finalizer完成来解决这个问题.这一般不是一般推荐的,但是对于这种特定情况,有些人认为这是一个可以接受的解决方案,因为难以跟踪所有创建的临时非管理对象.但明确的清理是正确的方法.但是,由于这样做的困难,所以这个“黑客”可能是可以接受的.请注意,此解决方案可能优于您提出的想法. 如果您想要尝试明确地清理,“不要使用COM对象的两个点”指南将帮助您记住保留对每个您创建的对象的引用,以便在完成后清理它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |