利用IDisposable接口构建包含非托管资源对象
程序员文章站
2022-05-06 10:33:40
托管资源与非托管资源 在.net中,对象使用的资源分为两种:托管资源与非托管资源。托管资源由CLR进行管理,不需要开发人员去人工进行控制,.NET中托管资源主要指“对象在堆中的内存”;非托管资源指对象使用到的一些托管内存之外的内资源(例如操作系统的资源),CLR不会管理这些资源,需要开发人员去控制。 ......
托管资源与非托管资源
在.net中,对象使用的资源分为两种:托管资源与非托管资源。托管资源由clr进行管理,不需要开发人员去人工进行控制,.net中托管资源主要指“对象在堆中的内存”;非托管资源指对象使用到的一些托管内存之外的内资源(例如操作系统的资源),clr不会管理这些资源,需要开发人员去控制。.net对象使用到的非托管资源主要有i/o流、数据库连接、socket连接、窗口句柄等直接与操作系统操作的相关资源。
管理非托管资源
当一个对象不再使用时,我们应该将它使用的非托管资源释放掉,归还给操作系统,不然等到clr将它在队中的内存回收之后。这部分内存就会变成不可达状态。只能等到整个应用程序运行结束后才能归还给系统。所以我们应当在该对象实例处于“可达”状态时,既有对象引用指向它时释放非托管资源。
利用idisposable接口构造含有非托管资源类型的对象
在.net类库中有一个idisposed的接口。几乎每一个使用非托管资源的类型都应该实现这个接口。那么如果我们看到实现此接口的类型,也应该第一时间想到该类型中包含非托管资源。idispose接口是管理对象非托管资源的一种原则。代码如下:
interface idisposable { void dispose(); } class abase:idisposable { bool _disposed = false; public bool disposed { get { return _disposed; } } public abase(){} public void dispose() { if(_disposed) { dispose(true); gc.suppressfinalize(this); _disposed = true; } } protected virtual void dispose(bool disposing) { if(disposing) { //release member's unmanaged resource } // release abase's unmanaged resource } ~abase { dispose(false); } } class a : abase { public a() { } protected override void dispose(bool disposing) { if(disposing) { // release member's unmanaged resource } // release a's unmanaged resource // release base class's unmanaged resource base.dispose(disposing); } } class b:a { public b() { } public void dosomething() { if(disposed)// if released, throw exception { throw new objectdisposedexception(...); } // do something here } protected override void dispose(bool disposing) { if(disposing) { // release member's unmanaged resource } // release b's unmanaged resource base.dispose(disposing); } }