微软Marshal.ReleaseComObject 方法的来龙去脉

目的:研究了很多微软调用COM 对象或者ActiveX控件的范例,都很少有用到Marshal.ReleaseComObject 方法。因此,对超图范例频繁使用该方法的原因产生了好奇。所以花2天时间集中研究了一下。

定义:递减所提供的运行库可调用包装的引用计数。

但实际上因为无论调用包装 COM 对象的托管客户端有多少,.net运行库可调用包装仅保留对该对象的一次引用。所以这个方法将导致.net运行库释放非托管 COM 对象上的所有引用。

(白话解释下:COM对象与.NET环境处理内存的机制不同,所以要让老的COM东东能够在新的.NET环境运行,必须给COM对象包装一下,让她打扮成.NET对象的样子。但有的东西是COM特有的,比如引用计数,这是COM对象处理内存的方法,有人调用我就+1,这样6个人在用我,引用计数=6;当计数=0的时候,表示没人用我啦,于是羞愧而自杀,从内存中消失。但.NET环境不是这样处理,所有事情都由自动啦。新老东西打交道的时候,.NET说,COM老弟,你还是自己管你自己吧。于是,在.NET环境调用COM对象,比如Layer,就必须让superMap控件自己在没人用的时候识相的走人。当然我们编程人员希望能够控制拉,这时候就是显式控制。微软提供的Marshal.ReleaseComObject 方法,就是让我们显示控制COM对象的生存。你调用这个方法,就是通过.NET环境,告诉COM对象,不用你了,马上消失。)

用途:此方法用于显式控制从托管代码使用的 COM 对象的生存期。应及时(或者在对象按指定的顺序必须释放时)使用此方法,来释放引用某些资源的基础 COM 对象。

还有隐式控制,在代码嵌套结束时自动释放。就像for循环中的int i = 0;变量一样,出了循环代码段,int i自动消失。如果你在循环中调用一个COM对象,那就不用显示控制释放。系统自动解决。在其它代码段的嵌套情况下一样。我想我看到的很多微软的范例,都是这种隐式控制的方法吧。例如很多朋友用SuperMap时会遇到时有时无的故障。在不知不觉间用了隐式控制感觉没有问题;有时候恰好调用COM的代码没有隐式处理,所以出现故障。

COM对象与.NET的交互是牵扯到多方面的知识,是一个复杂的庞大话题。有兴趣的话可以MSDN研究下。在与COM对象打交道的时候,最好把更多的精力投入到体会其体系结构方面。

posted @ 2009-12-28 12:55  遥望星空  阅读(691)  评论(0编辑  收藏  举报