gpt4 book ai didi

c# - 如何在 C# 2012 版中正确清理 Excel 互操作对象

转载 作者:行者123 更新时间:2023-11-30 12:48:56 24 4
gpt4 key购买 nike

我正在用 C# 编写一个应用程序,该应用程序将通过互操作打开 Excel 电子表格(2007 年,目前),执行一些操作,然后关闭。 “魔法”部分非常重要,因此该应用程序将包含对 Excel 生成的许多 COM 对象的许多引用。

我以前写过这种应用程序(实际上写过很多次),但我从未找到一种舒适、“好闻”的方法来与 COM 对象进行交互。问题部分在于,尽管进行了大量研究,但我仍然不能完全理解 COM,部分在于互操作包装器隐藏了很多可能不应该隐藏的内容。事实上,来自社区的许多不同、相互矛盾的建议只会让事情变得更糟。

如果您无法从标题中分辨出来,我已经完成了研究。标题暗指这篇文章:
How do I properly clean up Excel interop objects?

在 2008 年首次提出,这个建议在当时确实很有帮助和可靠(尤其是“切勿对 com 对象使用 2 个点”),但现在看来已经过时了。 2010 年 3 月,Visual Studio 团队发布了一篇博客文章,警告其他程序员 Marshal.ReleaseComObject [is] Considered Dangerous .文章引用了两篇文章,cbrumme's WebLog > ReleaseComObjectThe mapping between interface pointers and runtime callable wrappers (RCWs) ,暗示人们一直以来都在错误地使用 ReleaseComInterop(cbrumme:“如果您是一个客户端应用程序,使用适量的 COM 对象,这些对象在您的托管代码中自由传递,则不应使用 ReleaseComObject”)。

有没有人有一个中等复杂的应用程序示例,最好使用多线程,它能够成功地在内存泄漏(应用程序关闭后 Excel 继续在后台运行)和 InvalidComObjectExceptions 之间导航? 我正在寻找允许 COM 对象在创建它的上下文之外使用但在应用程序完成后仍然可以清除的东西:一种内存管理策略的混合,它可以有效地跨越托管/非托管鸿沟。

对讨论此问题的正确方法的文章或教程的引用将是一个非常受欢迎的选择。我最大的 Google-fu 努力返回了明显不正确的 ReleaseComInterop 方法。


更新:
(这不是答案)
发了没多久就发现了这篇文章:
VSTO and COM Interop by Jake Ginnivan

我已经能够通过扩展方法实现他将 COM 对象包装在“AutoCleanup”类中的策略,我对结果非常满意。虽然它没有提供允许 COM 对象跨越创建它们的上下文边界并仍然使用 ReleaseComObject 函数的解决方案,但它至少提供了一种简洁易用的方法-阅读解决方案。

这是我的实现:

class AutoCleanup<T> : IDisposable {

public T Resource {
get;
private set;
}

public AutoCleanup( T resource ) {
this.Resource = resource;
}

~AutoCleanup() {
this.Dispose();
}

private bool _disposed = false;
public void Dispose() {
if ( !_disposed ) {
_disposed = true;
if ( this.Resource != null &&
Marshal.IsComObject( this.Resource ) ) {
Marshal.FinalReleaseComObject( this.Resource );
} else if ( this.Resource is IDisposable ) {
( (IDisposable) this.Resource ).Dispose();
}
this.Resource = null;
}
}

}

static class ExtensionMethods {

public static AutoCleanup<T> WithComCleanup<T>( this T target ) {
return new AutoCleanup<T>( target );
}

}

最佳答案

您现在了解 COM 代理管理的 NetOffice 概念了吗?NetOffice 使用 com 代理和 IDisposable 模式的包装器类。NetOffice 保持代理的父->子关系。处理一个工作表,所有从实例(单元格、样式)等创建的子项也被处理。您还可以使用特殊事件或静态属性来观察应用程序中打开代理的数量。

看看这个文档片段: http://netoffice.codeplex.com/wikipage?title=Tec_Documentation_English_Management

您在教程文件夹中找到了一些用于 com 代理管理的 showstopper 项目

关于c# - 如何在 C# 2012 版中正确清理 Excel 互操作对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13179510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com