首页 新闻 会员 周边

C#非托管资源的释放疑问

0
悬赏园豆:50 [已解决问题] 解决于 2013-12-03 07:52

比如说有一个Socket实例,通过它又创建了一个DataWriter和一个DataReader,

_dataReader = new DataReader(_socket.InputStream);
_dataWriter = new DataWriter(_socket.OutputStream);

它们三个都有dispose方法,那我想要关闭它们时或者在异常的处理中,应该全部都调用一遍dispose还是只调用某个?

如果您很清楚这种情况的处理方法,能告诉我原因是什么吗?这个问题已经困扰我好久了。

皮毛君的主页 皮毛君 | 初学一级 | 园豆:145
提问于:2013-11-28 08:30
< >
分享
最佳答案
2

前几天刚好学习并整理了下,关于非托管资源的知识。 

我的观点是,使用using 关键字, 在异常处理的 finally 中都调用,dispose() 方法。

下面是我通过思维导图整理的,非托管资源的知识:

收获园豆:40
袁家小黑球 | 小虾三级 |园豆:1045 | 2013-11-28 10:22

多谢谢,看着挺全面,只是有点看不清楚。

皮毛君 | 园豆:145 (初学一级) | 2013-12-02 16:29

@Helloafer: 邮箱发我,我可以发给你

袁家小黑球 | 园豆:1045 (小虾三级) | 2013-12-02 16:41

@袁家小黑球: uuzfz@qq.com再次试谢谢了。

皮毛君 | 园豆:145 (初学一级) | 2013-12-03 07:46
其他回答(5)
1

个人见解: 以上的每个类都继承了IDispose接口,且类与类之间都相互独立的,所以每个类在释放非托管资源时,都应调用自己的Dispose方法。

Zery | 园豆:6151 (大侠五级) | 2013-11-28 09:13
0

可以用using处理,需要对每一个都释放的

平常心队长 | 园豆:1113 (小虾三级) | 2013-11-28 09:16

因为这个Socket要保持着连接,所以不能用using.

支持(0) 反对(0) 皮毛君 | 园豆:145 (初学一级) | 2013-12-02 16:31

@Helloafer: 出了这个方法连接还要保持吗?

支持(0) 反对(0) 平常心队长 | 园豆:1113 (小虾三级) | 2013-12-02 17:26

@平常心队长: 嗯,是的,其实这是一个WP8手机上的蓝牙的Socket,我要让它和一个蓝牙模块保持连接,才能流畅的控制玩具车。

支持(0) 反对(0) 皮毛君 | 园豆:145 (初学一级) | 2013-12-03 07:49
0

自己判断一下_dataReader和_dataWriter 是不是同一个流对象的引用就OK了。否则就都要释放

ReferenceEquals是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用。

大芝麻 | 园豆:4 (初学一级) | 2013-11-28 11:27
0

try{}catch(){}finally{dispose();}

梧桐雨2023 | 园豆:170 (初学一级) | 2013-11-29 10:21
0

调用Socket的Dispose(),垃圾回收器会检测和Socket有关的栈,并逐一调用终结器。

收获园豆:10
水晶途途 | 园豆:1443 (小虾三级) | 2013-11-29 11:33

谢谢,觉得你说的是我最想了解的方向。你说的意思不知道我理解的对不对。

1.是不是说Socket对象的Dispose方法调用之后,其它两个类的析构函数会被垃圾回收器调用,从而也相当于调用了他们Dispose方法?

2.如果上面的成立,那如果我自己建一个类引用一个外部Socket对象,当这个引用的Socket对象在外部被调用Dispose后,我的这个类也会被销毁了吗?如果不是,这要怎么理解呢?

支持(0) 反对(0) 皮毛君 | 园豆:145 (初学一级) | 2013-12-02 16:23

@Helloafer: 2的理解是错误的,自己的类会先进栈,Socket对象后进栈,所以Socket对象销毁后,自己的类不一定会销毁。建议你看看.NET 的内存管理机制,这个会告诉你,在什么情况下会触发内存回收,Dispose的作用以及什么样的对象会被回收。

支持(0) 反对(0) 水晶途途 | 园豆:1443 (小虾三级) | 2013-12-03 10:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册