7

Looking through the .NET documentation, specifically the WebRequest class, I don't see any information indicating that I should wrap an instantiation of it in a using statement. Even the provided example does not do this. In most examples online however, this is exactly what's done.

My question is then, how do I know specifically which classes need to be disposed? Is there a general rule of thumb or do you inspect class definitions to see if they somehow handle unmanaged resources?

  • 1
    Their provided examples are very poor when it comes to best practices. – Jesse C. Slicer May 11 '15 at 4:09
9

My question is then, how do I know specifically which classes need to be disposed?

Does it implement IDisposable? Yes? Then it needs to be disposed. If not, not. You can maybe get away without it in some apps (C# and modern operating systems in general are better about cleaning up after you), but it is still wrong®.

There are a very few framework classes that need Close (or something similar) called instead, and do not implement IDisposable, but these will say so in their documentation. These though are exceptions.

  • Good answer, thank you. I wish the documentation would provide information on what interfaces each class implements. I guess I can get that information from the Methods area. – transporter_room_3 Apr 9 '15 at 6:38
  • While true in general, there are also classes that implement IDisposable (because their base class does) but don't really need disposing. Examples include MemoryStream or WebClient. Though disposing them just to be sure is not wrong. – svick May 11 '15 at 0:20
  • 3
    There exist some classes that implement IDisposable, that should not be disposed. I mean, there is at least one: Task (Explained in Do I need to dispose of Tasks?). However, I would expect such cases to be very rare. – jhominal May 11 '15 at 12:27
  • @jhominal - very good counter-example. I agree that these should be fairly rare, and in any case it's best-practice to implement a finalizer alongside the Dispose pattern, so your unmanaged resources are effectively Dispose()d when the Disposable object is GCed. That's not instant, of course, and so if you're implementing a highly parallel or high-performance piece of code that may grab and release unmanaged resources at a high rate, making sure these get disposed of quickly with an explicit Dispose() (or using block) is a bigger deal. For most applications, the finalizer's good enough. – KeithS Apr 20 '17 at 14:35
2

In most examples online however, this is exactly what's done

Not sure how; neither WebRequest nor its concrete descendant HttpWebRequest do in fact implement IDisposable, so this

 using (System.Net.WebRequest wr = new System.Net.HttpWebRequest())
 {
     //What?
 }

does not compile. In fact what I find when I google around this topic is mostly speculation as to why WebRequest doesn't implement IDisposable...


The MSDN documentation isn't by any means perfect, but does tell you when a class implements IDisposable; see for example the Remarks section for StreamWriter.

  • 1
    You are right, it was WebResponse that was in a using statement. And it does infact show in the documentation, that it explicitly implements the IDisposable interface. One version of WebRequest I stumbled upon in a google search seem to have implemented IDisposable link. – transporter_room_3 Apr 9 '15 at 11:06
-1

My question is then, how do I know specifically which classes need to be disposed?

You could look into the MSDN documentation for each class. That would be boring and cumbersome, but work.

If you are using a Visual Studio version that supports it, you should turn on Static Code Analysis in the options of your project. It will give you a warning for each object that you did not properly dispose, either through a using block or implementing a proper dispose pattern yourself in case of class members.

  • 1
    I've no idea why this was downvoted. I use the Visual Studio analysis tools precisely for this purpose too. – RubberDuck Apr 20 '17 at 15:57
-2

how do I know specifically which classes need to be disposed?

In short the GC in Windows, some may argue .NetFx, will handle the management of resources and its life-span on the system. In short, you don't have to worry about managing it in .Net like you do in the unmanaged sphere (C, C++, etc.)

In general, objects that implement IDisposable have the propensity to consume large quantities of resources (CPU, RAM, HDD, etc). Therefore, the developer decided to extend the IDisposable interface to manually provide the logic to get rid of those resource hogs.

As a point of clarification, the using statement is more of a syntactical sugar keyword for try...finally. There are more guts and glory behind the logic of the using statement but it all boils down to try..finally; as a word of full-disclosure, using statement does not implement catch, that is all on you for that.

Is there a general rule of thumb or do you inspect class definitions to see if they somehow handle unmanaged resources?

Again, any "object" created inherits by default Object. This is how .Net effectively becomes a managed utility. Even if you don't define an explicit inheritance to Object, the compiler makes it inherit Object.

The only resources you need to be concerned with are 3rd Party unverified libraries (DLL). If you try to attach it to a .Net project, it will scream "bloody murder" at you until you fix it properly.

  • 2
    Not all IDisposable objects utilize large amounts of anything. In fact rarely are they disposable for that reason. More often it's because they utilize special resources that are limited or tightly controlled, e.g. network ports or hardware devices. – whatsisname May 13 '18 at 0:18
  • @whatsisname Refer to In general, objects that implement IDisposable have.... does not mean All. Network Ports & Hardware Devices are resources and usually leveraging those resources needs to be managed so that the holding "pointer" is released. Otherwise you would end up with a "leak" scenario. – GoldBishop May 13 '18 at 0:36
  • I've made display code go very, very wrong more than once from failing to dispose of GDI resources. – Loren Pechtel May 13 '18 at 4:25
  • @GoldBishop: the point is, your reasoning you cite as the "in general" is in fact not "in general" but a small minority, if any of them. I can't even think of a single IDisposable object that uses any more memory than other ordinary classes. The IDisposable documentation talks a great deal about freeing unmanaged or system resources, and almost nothing about processor or memory usage. – whatsisname May 13 '18 at 5:27
  • I think this answer confuses different notions of "resource". Adding Dispose() will certainly not affect the use of CPU resources! Also, it is wrong to say the GC manages resources - if that was the case we wouldn't need Dispose in the first place. GC only manages managed memory, any other external resource must be handled manually. It is not a question of the amount of resources consumed but of the kind of resources. – JacquesB May 13 '18 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.