如何正确清理Excel的互操作对象在C#中,2012年版 [英] How to properly clean up Excel interop object in C#, 2012 edition

查看:189
本文介绍了如何正确清理Excel的互操作对象在C#中,2012年版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写C#应用程序,将通过互操作打开一个Excel US preadsheet(2007年,现在),做一些魔术,然后关闭的过程。 魔术师的部分是不平凡的,所以这个应用程序将包含多次提到用Excel产生了许多COM对象。

我写这类应用之前(太多次,其实),但我从来没有发现一个舒适,好闻的方式来与COM对象交互。问题部分是,尽管显著的研究,我还是不完全理解COM和部分的互操作包装隐藏多,可能不应该被隐藏。事实上,有这么多不同的,相互矛盾的建议从社区只会使事情变得更糟。

如果你不能从标题说,我做我的研究。标题暗示了这个帖子:
<一href="http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c-sharp">How妥善清理在C# Excel的互操作对象

首先要求在2008年,该建议是真正有用的和固体的时候(特别是禁止使用2点与COM对象位),但现在看来已经过时了。 2010年3月,在Visual Studio团队发表了一篇博客文章警告同胞的程序员的<一个href="http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx"相对=nofollow> Marshal.ReleaseComObject的[是]认为是危险的。文章中提到的两篇文章, cbrumme的博客> ReleaseComObject的和<一href="http://blogs.msdn.com/b/mbend/archive/2007/04/18/the-mapping-between-interface-pointers-and-runtime-callable-wrappers-rcws.aspx"相对=nofollow>接口指针和运行时可调用包装(的RCW)之间的映射,这表明人们一直在使用ReleaseComInterop错误一直以来(cbrumme:如果你是使用COM对象数量适中,客户端应用程序您正使用的管理code传来传去自由,你不应该使用ReleaseComObject的)。

有没有人有一个比较复杂的应用程序,$ P $的pferably使用多线程的例子,即能内存泄漏的成功驾驭(Excel将继续在后台运行后,该应用程序已关闭),并InvalidComObjectExceptions? 我在寻找的东西,这将允许它在其中创建,但仍然可以清理一旦应用程序完成它的上下文之外使用的COM对象:存储管理策略的混合从而可以有效地跨越托管/非托管的鸿沟。

的引用,讨论了正确的方法,这个问题将是一个更加AP preciated替代的文章或教程。我最好的谷歌福的努力已经回到显然不正确ReleaseComInterop方法。


更新:
(这不是一个答案)
我发现这篇文章发布后没多久:
VSTO和COM互操作由杰克Ginnivan

我已经能够实现他通过一个扩展方法包装在AutoCleanup类COM对象的策略,我pretty的满意的结果。虽然它不提供一个解决方案,以允许COM对象越过它们被创建的上下文的边界,但仍然使用了ReleaseComObject的功能的的,但是它至少提供一个整齐和易于-read解决方案。

下面是我实现的:

 类AutoCleanup&LT; T&GT; :IDisposable的{

    公共科技资源{
        得到;
        私定;
    }

    公共AutoCleanup(T资源){
        this.Resource =资源;
    }

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

    私人布尔_disposed = FALSE;
    公共无效的Dispose(){
        如果(!_disposed){
            _disposed = TRUE;
            如果(this.Resource = NULL和放大器;!&安培;
                 Marshal.IsComObject(this.Resource)){
                Marshal.FinalReleaseComObject(this.Resource);
            }否则,如果(this.Resource是IDisposable接口){
                ((IDisposable接口)this.Resource).Dispose();
            }
            this.Resource = NULL;
        }
    }

}

静态类ExtensionMethods {

    公共静态AutoCleanup&LT; T&GT; WithComCleanup&LT; T&GT;(这件T目标){
        返回新AutoCleanup&LT; T&GT;(目标);
    }

}
 

解决方案

现在没有你的NetOffice概念COM代理管理? NetOffice使用包装类COM代理和IDisposable模式。 NetOffice保持对代理的父 - >子关系。配置一个工作表,并从实例(细胞,样式)都创造了蔡尔兹等也被释放。你也可以使用一个特殊的事件或静态属性来观察开放代理的数量在你的应用程序。

只是把这个文档片段一起来看看: 的http://netoffice.$c$cplex.com/wikipage?title=Tec_Documentation_English_Management

你找到一些搅局者项目COM代理管理教程文件夹

I am in the process of writing an application in C# which will open an Excel spreadsheet (2007, for now) via interop, do some magic, then close. The "magic" part is non-trivial, so this application will contain many references to many COM objects spawned by Excel.

I have written this kind of application before (too many times, in fact) but I've never found a comfortable, "good smell" approach to interacting with COM objects. The problem is partly that, despite significant study, I still don't perfectly understand COM and partly that the interop wrappers hide much that probably shouldn't be hidden. The fact that there are so many different, conflicting suggestions from the community only makes matters worse.

In case you can't tell from the title, I've done my research. The title alludes to this post:
How to properly clean up Excel interop objects in C#

First asked in 2008, the advice was really helpful and solid at the time (especially the "Never use 2 dots with com objects" bit) but now seems out of date. In March of 2010, the Visual Studio team posted a blog article warning fellow programmers that Marshal.ReleaseComObject [is] Considered Dangerous. The article referred to two articles, cbrumme's WebLog > ReleaseComObject and The mapping between interface pointers and runtime callable wrappers (RCWs), suggesting that people have been using ReleaseComInterop incorrectly all along (cbrumme: "If you are a client application using a modest number of COM objects that are passed around freely in your managed code, you should not use ReleaseComObject").

Does anyone have an example of a moderately complex application, preferably using multiple threads, that is able to successfully navigate between memory leaks (Excel continues running in the background after the application has closed) and InvalidComObjectExceptions? I'm looking for something which will allow a COM object to be used outside of the context in which it was created but can still be cleaned up once the application is finished with it: a hybrid of memory management strategies which can effectively straddle the managed/unmanaged divide.

A reference to an article or tutorial that discusses a correct approach to this problem would be a much appreciated alternative. My best Google-fu efforts have returned the apparently incorrect ReleaseComInterop approach.


UPDATE:
(This is not an answer)
I discovered this article not long after posting:
VSTO and COM Interop by Jake Ginnivan

I've been able to implement his strategy of wrapping COM objects in "AutoCleanup" classes via an extension method, and I'm pretty happy with the result. Though it does not provide a solution to allow COM objects to cross the boundaries of the context in which they were created and still makes use of the ReleaseComObject function, it does at least provide a neat and easy-to-read solution.

Here's my implementation:

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 );
    }

}

解决方案

did you now the NetOffice concept for COM proxy management? NetOffice use wrapper classes for com proxies and the IDisposable pattern. NetOffice keep the parent->child relationship for proxies. dispose a worksheet and all created childs from the instance(cells, styles), etc. was also disposed. you can also use a special event or static property to observe the count of open proxies in your application.

just take a look in this documentation snippet: http://netoffice.codeplex.com/wikipage?title=Tec_Documentation_English_Management

you find some showstopper projects for com proxy management in the tutorials folder

这篇关于如何正确清理Excel的互操作对象在C#中,2012年版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆