How do we distinguish between managed and unmanaged resources in C#? Is TextFieldParser unmanaged?

醉酒当歌 提交于 2019-12-23 04:47:14

问题


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)))

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

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. 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.


回答1:


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

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.

EDIT:

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();

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.

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:

  • 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.

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).




回答2:


The use of any classes implment IDisposable interface should be either wrapped in using (...) {} or be disposed nicely where appropriate.



来源:https://stackoverflow.com/questions/34608787/how-do-we-distinguish-between-managed-and-unmanaged-resources-in-c-is-textfiel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!