Net下Arcgis engine COM对象的释放问题
来源:互联网 发布:诲女知之乎单独翻译 编辑:程序博客网 时间:2024/06/03 19:39
问题描述:
最近的项目中涉及到离线编辑的问题,我的做法是根据业务需求在本地建一个FileGeodatabase数据库,在编辑过程中需要重新同步数据库时候,需要删除现有离线数据库,但是即使使用了System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o),在删除数据库的时候,任然提示数据库文件被另外一个线程占用。
问题分析:
ArcObject.Net是在COM的基础上构建的, 因而客户只能在RCWs 的基础上进行COM组件的调用,COM对象是分配在非托管堆上的,因而GC无法管理其生命周期,这也会造成一些某名奇妙的问题,比如资源无法释放的问题。根据AO的开发文档,我们可以使用ComRelease来管理这些非托管资源,使用.net reflector看了一下ComReleaser的实现(AO 10.1中ComReleaser的实现在ESRI.ArcGIS.ADF.Connection.Local中),具体如下:
public class ComReleaser : IDisposable{// Fieldsprivate ArrayList m_array;// Methodspublic ComReleaser();public void Dispose();protected virtual void Dispose(bool disposing);protected override void Finalize();public void ManageLifetime(object o);public static void ReleaseCOMObject(object o);}
从上面的代码中可以看出ComReleaser是实现了IDispose接口的对象,因而可以直接使用using来管理其生命周期,这个对象的功能的关键功能就是释放COM对象,打开他的Dispose方可以看到,其实他是循环调用RelaseComObject来减少对象链表中RCWs的引用计数,根据MSDN的问题,这一功能其实可以直接使用FinalReleaseComObject来实现,因而可以使用如下方式来实现同样的功能:
public static void ReleaseCom(object o){try{System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o);}catch { }finally{o = null;}}
然而!!!!!这样并没用卵用,在进行删除离线数据库的时候,发现离线数据库文件无法删除,出现进程占用的问题,逐层排查,可以断定原因在于在数据同步功能块,资源没有正确释放,因而我采用如下方式进行释放:
public void Synchronization(IPolygon updateExtent){_updatePolygon = updateExtent;if (_updatePolygon == null) return;IMapDocument masterDoc = new MapDocumentClass();masterDoc.Open(_masterGeoDataBase);IMapDocument offlineDoc = new MapDocumentClass();offlineDoc.Open(_offlineGeoDataBase);IMap onlyOfflineMap = offlineDoc.get_Map(0);IMap onlyMasterMap = masterDoc.get_Map(0);for (int offlineLayerIndex = 0; offlineLayerIndex < onlyOfflineMap.LayerCount;++offlineLayerIndex){ILayer curOfflineLayer = onlyOfflineMap.get_Layer(offlineLayerIndex);string curLayerName = curOfflineLayer.Name;ILayer masterLayer = Utility.GetLayerByName(curLayerName, onlyMasterMap);UpdateForDelete(masterLayer, curOfflineLayer);UpdateForNewOrModify(masterLayer, curOfflineLayer);Utility.ReleaseCom(curOfflineLayer);Utility.ReleaseCom(masterLayer);}offlineDoc.Save();masterDoc.Save();offlineDoc.Close();masterDoc.Close();Utility.ReleaseCom(offlineDoc);Utility.ReleaseCom(masterDoc);Utility.ReleaseCom(onlyOfflineMap);Utility.ReleaseCom(onlyMasterMap);}
满怀高兴的F5,BUG依然,好想召唤我无所不能的大圣。难道是还有资源没有释放?找遍代码也没找到,只能Google了,找到两篇博客http://blog.csdn.net/lion_wing/article/details/4429179 和http://www.cnblogs.com/tendzzss/archive/2011/11/11/2245627.html ,第二篇文章进行了详细案例测试,得出了不同的应用场景,第一篇博中提到的一句话读自己的帮助很大,RCW是由GC 管理,在垃圾收集的时候会将该对象置于Finalize队列,由GC调用其析构函数,释放COM对象,《精通.Net互操作》一书中也提到了,RCW会保持非托管资源的引用直至运行库对包装执行垃圾回收,但是GC是不确定,那么按照这个意思,清完计数后,我直接GC.Collect()强制进行垃圾回收,是不是就能完全释放COM对象了,然后,然后,程序完美通过。
有什么不妥之处,欢迎交流:E-mai:zhaozhipeng1000@126.com ; QQ 群: 191593647
- Net下Arcgis engine COM对象的释放问题
- ArcEngine的COM对象在.NET中的释放问题
- 立即释放.net下的com组件
- 释放.net下的com组件
- 立即释放.net下的com组件
- 立即释放.net下的com组件
- 立即释放.net下的com组件
- ArcEngine中com对象的释放问题
- ae的com对象在dotnet中的释放问题
- 释放Com对象的方法.
- 对com对象的释放
- .NET对象的释放
- Arcgis Engine 分解对象
- C#托管环境下释放COM对象
- .net下的AO对象的安全释放
- ArcGIS Engine中正确释放打开资源
- ArcGIS Engine中正确释放打开资源
- ArcGIS Engine中正确释放打开资源
- DirectX3D 9.0 第二天
- 开源的作业调度框架 - Quartz.NET
- C语言字符串中使用宏替换
- 反素数的总结
- openstack中有关虚拟机cpu绑定总结
- Net下Arcgis engine COM对象的释放问题
- 一个基于QR Code encoder的 php 扩展,更高效的生成二维码
- 7.21CSS初步
- Qt数据库:(六)QSqlTableModel
- Mac OS 环境下 安装 Asp.Net及使用Yeoman 创建Asp.Net 项目
- Keil MDK中的Code, RO-data , RW-data, ZI-data分别代表什么意思
- iTween的一个潜在BUG
- SVN分支与合并
- 告别迷茫与忧伤的程序员