我recently learned如何使用Microsoft.VisualBasic.FileIO.TextFieldParser
来解析文本输入。在给我的示例中,使用关键字TextFieldParser
using
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(str)))
虽然在some further researches之后,我注意到using
使用TextFieldParser
关键字的做法并不普遍。
据我所知,.Net
Framework同时拥有托管和非托管资源。当我们使用非托管资源时,我们应该worry about内存泄漏,因此我们应该处理我们使用的非托管资源。最好的方法是将它们放在using
上下文中。
所有这些让我想起了两个问题,一个是特别的,一个是一般的。以下是我的问题:
X
内容,或类似内容,甚至是检查来自MSDN的内容 - 如果有任何检查 - 将会这样做。在我的简短编程经验中,我被告知了一些指导,例如(i)大多数.Net
类被管理,(ii)System.Drawing类有一些非托管资源,(iii)要小心所有数据库,网络,和COM类,因为它们通常是不受管理的等等......而且这个列表一直在继续添加到现在。但我想知道是否有任何明确的方式来了解这一点?如果经验丰富的人有助于进一步指导我解决这个问题,我将非常感激。
答案 0 :(得分:2)
你错过了这一点。每当任何课程实施IDisposable
时,您应该在完成任务后致电Dispose
。
班级是否使用非托管资源是课堂内部的资源,你根本不应该关心它。如果您没有明确地处理该类,那么使用非托管资源的每个类都应该有一个终结器来清除那些非托管资源。 Dispose
只是允许您以更确定和更直接的方式清理其资源(管理和非管理,尽管这并不一定意味着立即释放内存)。例如,Dispose
FileStream
会立即释放文件句柄,而如果您不Dispose
(或Close
),该文件将被打开,直到下一个收集和定稿。
修改强>
为了表明清理托管资源可能还需要Dispose
,我们只需要查看事件处理程序。特别是,当您订阅一个比您的生命周期更长的类的事件时,情况如下:
var control = new MyHelperControl();
MyParentForm.Click += control.DoSomething();
现在,即使control
超出范围,只要MyParentForm
它仍然存在 - 它仍然由事件处理程序引用。当父级具有与整个应用程序相同的生命周期时,同样的问题会变得荒谬 - 这可能是一个巨大的内存泄漏。一个例子是在应用程序的主窗体上或静态事件上注册事件处理程序。
Dispose
可能还会发生其他事情。例如,再次使用Windows表单,当您在Dispose
上调用Control
时,会发生很多事情:
Dispose
,它们也会被释放,因为它们都有终结器,但它可能需要更多的时间 - 当你创建并销毁很多这些对象时尤其痛苦。例如,GDI +对象句柄的供应有限,如果你用完了,你就会得到OutOfMemoryException
并且你已经离开了。有趣的是,非托管资源对至少很重要,实际上 - 他们总是有终结者。托管资源比较棘手,因为您或多或少地被禁止在终结器中处理托管引用(因为它们可能已经被释放,或者它们可能正处于释放状态,或者它们可能开始被释放你的终结者的中间......这很复杂)。所以做MyParentForm.Click -= this.OnClick;
对你的终结者来说并不是一件好事 - 更不用说它会要求你让每一个这样的课程都可以完成,而这并不是完全免费的,特别是当你期望终结者实际上运行(当您执行Dispose
时,会通知GC此实例不再需要最终确定。)
答案 1 :(得分:1)
使用任何类implment IDisposable接口应该使用(...){}包装,或者在适当的地方妥善处理。