我们如何区分C#中的托管资源和非托管资源?TextFieldParser是不受管理的吗? [英] How do we distinguish between managed and unmanaged resources in C#? Is TextFieldParser unmanaged?

查看:71
本文介绍了我们如何区分C#中的托管资源和非托管资源?TextFieldParser是不受管理的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近学习如何使用 Microsoft.VisualBasic.FileIO.TextFieldParser 来解析文本输入.在给我的示例中,使用关键字 using

I recently learned how to use Microsoft.VisualBasic.FileIO.TextFieldParser to parse a text input. In the example given to me, the TextFieldParser is called using the keyword using

using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(str)))

尽管在一些之后://stackoverflow.com/questions/3507498/reading-csv-file>更多

Though after some further researches, I notice that the practice of using using keyword for TextFieldParser is not universal.

据我了解, .Net 框架同时具有托管和非托管资源.当我们使用非托管资源时,我们应该担心内存泄漏和因此,我们应该注意处理我们使用的非托管资源.最好的方法是通过使用上下文将它们放在上.

As far as I understand, .Net Framework has both managed and unmanaged resource. And when we use unmanaged resource, we should worry about memory leak and thus we should take care of the disposal of the unmanaged resource we use. One best way to do this is by putting them on using context.

所有这些促使我想到两个问题,一个是特殊问题,另一个是一般问题.这是我的问题:

All these drive me to have two questions in my mind, one particular and one general. Here are my questions:

  1. 特别之处:TextFieldParser是实际托管还是非托管?
  2. 一般:是否有确定方式让我们知道资源是托管的还是非托管的(例如查看类中的 X 事物,等等),甚至检查
  1. The particular: Is TextFieldParser actually managed or unmanaged?
  2. The general: Is there a definite way for us to know if a resource is managed or unmanaged(such as looking at X thing in the class, or such alike, or even check something from MSDN - if any should be checked - will do). I was told some guidance along my short programming experience such as that (i) most of the .Net classes are managed, (ii) System.Drawing classes have some unmanaged resources, (iii) beware of all database, network, and COM classes because they are typically unmanaged, etc... and the list goes on which I keep adding till now. But I wonder if there is any definite way to know this?

如果有经验的人可以帮助我进一步指导这个问题,我将不胜感激.

I would really appreciate if the more experienced could help to further guide me on this issue.

推荐答案

您错过了重点.每当任何类实现 IDisposable 时,完成后都应调用 Dispose .

You're missing the point. Whenever any class implements IDisposable, you should call Dispose when you're done with it.

该类是否使用非托管资源都属于该类的内部,所以您根本不需要关心它.每个使用非托管资源的类也应该有一个终结器,如果您没有明确处理该类,则该终结器将清除那些非托管资源. Dispose 仅允许您以更具确定性和立即性的方式清理其资源(托管和非托管,但这不一定意味着立即释放内存).例如, Dispose 放入 FileStream 将立即释放文件句柄,而如果您不 Dispose (或 Close ),该文件将一直打开直到下一次收集并完成.

Whether the class uses unmanaged resources or not is internal to the class, you shouldn't care about it at all. Every class that uses unmanaged resources should also have a finalizer that clears up those unmanaged resources if you didn't dispose of the class explicitly. Dispose just allows you to clean its resources (both managed and unmanaged, though this doesn't necessarily mean freeing up the memory immediately) in a more deterministic and immediate fashion. For example, Disposeing a FileStream will release the file handle immediately, while if you don't Dispose (or Close), the file will be opened until the next collection and finalization.

为了表明清理托管资源也可能需要 Dispose ,我们只需要查看事件处理程序即可.特别是,当您订阅一个具有比您更长的生存期的类的事件时:

To show that Dispose may also be necessary to clean up managed resources, we only have to look at event handlers. In particular, the case when you're subscribing on an event of a class that has a longer lifetime than you do:

var control = new MyHelperControl();
MyParentForm.Click += control.DoSomething();

现在,即使 control 超出范围,只要 MyParentForm ,它也将继续存在-事件处理程序仍会引用它.当父级与整个应用程序具有相同的生存期时,相同的问题就会变得荒谬无比,这可能是一个巨大的内存泄漏.一个示例是在应用程序的主要形式或静态事件上注册事件处理程序.

Now, even if control goes out of scope, it will survive as long as MyParentForm - it's still referenced by the event handler. The same problem grows to absurd proportions when the parent has the same lifetime as the whole application - that's can be a huge memory leak. An example would be registering event handlers on the main form of an application, or on a static event.

Dispose 中可能还会发生其他事情.例如,再次使用Windows窗体,当您在 Control 上调用 Dispose 时,会发生很多事情:

There might also be other things that happen in the Dispose. For example, again with Windows forms, when you call Dispose on a Control, a whole lot of things happen:

  • 所有非托管资源均已释放.因为Winforms控件在一定程度上是本机控件的包装,所以通常这是很多资源-控件本身,任何笔,画笔,图像...所有这些都是本机资源.如果您忘记了 Dispose ,它们也会被释放,因为它们都有终结器,但是可能要花更多的时间-当您创建和销毁许多对象时,这尤其痛苦.例如,GDI +对象句柄的供应有限,如果用完了,您会得到 OutOfMemoryException 而出局.
  • 处置所有子控件.
  • 删除所有上下文菜单处理程序(请记住,上下文菜单是一个单独的组件,仅链接到另一个控件).
  • 删除所有数据绑定.
  • 从父容器中删除本身(如果有).
  • 如果控件是一个具有自己的消息循环的窗口,请终止该消息循环.
  • All the unmanaged resources are released. Since Winforms controls are wrappers of the native controls to an extent, this is usually a lot of resources - the control itself, any pens, brushes, images... all of those are native resources. They will also be released if you forget a Dispose, since they all have finalizers, but it might take more time - which is especially painful when you create and destroy a lot of those objects. For example, there's a limited supply of GDI+ object handles, and if you run out, you get OutOfMemoryException and you're out.
  • Dispose of all sub-controls.
  • Remove any context menu handlers (remember, context menu is a separate component that's only linked to another control).
  • Remove any data bindings.
  • Remove itself from the parent container, if any.
  • If the control is a window with its own message loop, kill the message loop.

有趣的是,非托管资源的确对最少至关重要-它们始终具有终结器.托管资源比较棘手,因为您或多或少被禁止在终结器中处理托管引用(因为它们可能已经被释放,或者它们可能正在释放中,或者它们可能开始在中间释放).终结器的代码...很复杂).因此,在终结器中执行 MyParentForm.Click-= this.OnClick; 并不是一件好事-更不用说它要求您将每个此类都终结化,而这并不是完全免费的,尤其是当您希望终结器实际运行时( Dispose ,当您执行 Dispose 时,GC会被警告该实例不再需要终结器).

The funny part is that the unmanaged resources matter the least, really - they always have a finalizer. The managed resources are trickier, because you're more or less forbidden to handle managed references in a finalizer (because they might have already been released, or they might be in the middle of being released, or they might start being released in the middle of your finalizer... it's complicated). So doing MyParentForm.Click -= this.OnClick; is not a good thing to have in your finalizer - not to mention that it would require you to make every such class finalizable, which isn't exactly free, especially when you expect the finalizer to actually run (when you do a Dispose, the GC is alerted that this instance no longer needs a finalization).

这篇关于我们如何区分C#中的托管资源和非托管资源?TextFieldParser是不受管理的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆