I've been trying to figure this one out.

I was under the impression that when a class method contains any resources, once the method has reached the end of the code and returns it's result (or nothing in the case of void), that all of those resources are gobbled up by the garbage collector and released back to the system.

If this is true, why would anyone ever bother disposing of something, managed or unmanaged? If I have a form that displays data in a DataSet or Array or whatever, those resources need to persist and when the form is closed, the form and all the components and resources associated with it should be released as well right?

If I have a connection to a data source, and it is called in a method, once the method is done (even if the programmer forgets to close the connection) the connection, connection string etc...should all be released from memory right?

I don't seem to understand why it would be necessary to bother with disposing of something that should be disposed of automatically.

Besides, how would someone know what kind of resources are unmanaged? Is there a list somewhere?

Recommended Answers

All 10 Replies

Member Avatar for embooglement

Well, if they want the resources to be released before the method returns, for one. For instance, my friend and I used XNA to build a game for XBox, which has a much smaller amount of RAM than a pc. So we attempted to dispose of resources that were no longer in use mid-function as to free up some memory, because we kept running out of memory. This didn't work. Which brings me to my next point: managed resources are at the mercy of the garbage collector, and in fact are not released when the method returns, but rather when the garbage collecting algorithm signifies that they are no longer in use. Unmanaged resources are though.

A connection to a database has resources that aren't managed by the CLR. These are owned by the OS, and if you don't dispose of the object, the OS doesn't know that it's ok to clean up those resources.

Also, the Garbage Collector runs when it 'feels' it needs to, so object created in methods hang around during the execution of your program until the GC runs. If you have a small program, this could be delayed until the program exits. If you have unmanaged resources, it's possible that the OS will run out of 'slots' to handle these.

The easiest way to deal with this is the using clause, it will call the dispose method for you:

using (SqlConnection sc = new SqlConnection()) {
    ... blah blah blah code
}

This is syntactic sugar for:

SqlConnections sc = new SqlConnection();
try {
    ... blah blah blah code here ...
} finally {
    if (sc != null) {
        ((IDisposable)sc).Dispose();
    }
}

The rule to remember is that if it implements IDisposable, you should Dispose() it.

Very good point embooglement...I suppose a developer has a general idea what system requirements their final product will require, RAM quantity being one of them. Disposing of something in mid function when it is no longer needed could reduce the RAM cost of the application.

Momerath...how do I know if something implements IDisposable...

Surely no one browses through the documentation of every function called to check if it uses IDisposable, applications would take decades to write...would it be a safe assumption that if I am done with something to use intellisense to see if something has a .Dispose() method? If it does, I should use it?

Also, is it necessary to write the function ((IDisposable)sc).Dispose(); or would sc.Dispose(); suffice?

Also, as I am discussing with embooglement in a different thread the concept and implementation of interfaces...with IDisposable being an interface...doesn't its implementation require a class and a Dispose() method to be defined somewhere? Or does the system have that automatically defined somewhere to handle the Dispose() method?

I guess what I'm saying is, in the absence of all other code, would building a connection to a SqlServer, opening the connection and then closing the connection and then simply calling ((IDisposable)sc).Dispose(); actually dispose of the resource? Or is something else needed?

Momerath...how do I know if something implements IDisposable...

You read the documentation on the method.

Surely no one browses through the documentation of every function called to check if it uses IDisposable,

Objects implement IDisposable, not functions. And how do you know how to use an object without reading the documentation on it?

would it be a safe assumption that if I am done with something to use intellisense to see if something has a .Dispose() method? If it does, I should use it?

Yes and Yes.

Also, is it necessary to write the function ((IDisposable)sc).Dispose(); or would sc.Dispose(); suffice?

No, you don't need to cast it into an IDisposable. I was just showing you what using is translated into by the compiler.

with IDisposable being an interface...doesn't its implementation require a class and a Dispose() method to be defined somewhere?

Yes it does. That is the whole point of interfaces, to require that objects that implement them have the methods, properties, events and/or delegates defined by that interface. If you were to create a class that had an unmanaged resource you should implement IDisposable in it. This tells other programmers that they need to call the dispose method, and what the name of the dispose method is :) There is no requirement that you do so, it's just a programming convention that most people agree helps.

As a side, in .NET, Close() and Dispose() are the same method, Close() just calls Dispose() (at least I haven't found one that doesn't, yet :))

I guess what I'm saying is, in the absence of all other code, would building a connection to a SqlServer, opening the connection and then closing the connection and then simply calling ((IDisposable)sc).Dispose(); actually dispose of the resource? Or is something else needed?

Yes, it would dispose of the unmanaged resource. The actual object clean up has to wait for the Garbage Collector.

momerath,

There are many objects (sorry for calling them methods before, I was very sleepy) that I use that I don't read documentation on.

I learned how to build and use an SqlConnection object by searching around the internet for examples (plus intellisense helps if you have a general idea of what an object needs to be used correctly). But until recently I didn't know that it implimented any type of "resource" that needed to be disposed. I assumed, incorrectly, the method ended, the objects and anything associated with them are gone.

I'm a little confused though.

If I use this:

class UnmanagedResourcesClass : IDisposable
{
//some code with unmanaged resources
}

Do I need to define somewhere what Dispose() does? I mean if I just create a method called public void Dispose() {}; what good does that do? There is no code for it to execute if it is called...

If I just use:

class UnmanagedResourcesClass
{
//some code with unmanaged resources
}

and after a SqlConnection object is used, I use MyObject.Dispose();

will that alone dispose of the unmanaged resources? Or do I need to define Dispose(); somewhere in the class?

I'm lost because, if I need to define what Dispose() does...what exactly do I put in the method? Don't all objects that need to dispose unmanaged resources use the same process to dispose of them?

Read the documentation sometime. You never know everything an object does unless you do. I still find things that I didn't realize were there in objects I use all the time (I said read, not memorize. If you read it then there is a chance you'll go "hmm, didn't I read that this object can do that if I just make the right call? Let's check the documentation!")

Yes, you'll need to implement Dispose() in your class. If you don't, the compiler won't compile the class. Try it :) The idea behind implementing interfaces is that they are a contract, and other programmers using your objects will have to assume that you've met that contract, and that your Dispose() method actually has a purpose and does something. If you violate this contract repeatedly, you'll find that people will stop using your code, or you might become unemployed.

And no, unless you actually call the Dispose() method (or use a using block) the Dispose() method will not be called on the SqlConnection. Let's say you create some class that encapsulates a SqlConnection. Since the user of your class won't have direct access to the SqlConnection, you'll have to ensure that your class, somewhere, disposes of the object. You can do this by implementing IDisposable and placing the call to SqlConnection.Dispose() in the Dispose() method you define. Or you could create a finalizer and call Dispose() there (though that has its own issues) and not have to implement IDisposable at all. Like most things in programming, there are many different ways to handle things.

Most likely you will not be writing code that uses unmanaged resources, unless you use unsafe, COM objects or Interop calls; or, as mentioned above, you are encapsulating or extending an object that does.

momerath,

For my own education I looked up SqlConnection Class on the MSDN site.

In the "Methods" section there is a chapter on the "SqlConnection.Dispose Method." There it gives an example of how to implement it. Here's the example:

Example

[Visual Basic, C#, C++] The following example creates a SqlConnection and then disposes of it.

[Visual Basic, C#, C++]Note This example shows how to use one of the overloaded versions of Dispose. For other examples that might be available, see the individual overload topics.

[Other examples removed from quote]

[C#]
public void SqlConnectionHereAndGone()
{
SqlConnection myConnection = new
SqlConnection("Initial Catalog=Northwind;Data Source=localhost;Integrated Security=SSPI;");
myConnection.Open();
//Calling Dispose also calls SqlConnection.Close.
myConnection.Dispose();
}

This example to me suggests that Dispose() is a method of the SqlConnection object and is defined already.

For example, if I do SomeVariable.toString(); I don't need to define anywhere what toString() does...it's already defined somewhere in the framework and I can just call it.

But then I thought I would look up Cleaning Up Unmanaged Resources. In that article it states that you should implement a dispose method and then proceeds to provide the following lengthy example:

// Design pattern for the base class.
// By implementing IDisposable, you are announcing that instances
// of this type allocate scarce resources.
public class BaseResource: IDisposable
{
   // Pointer to an external unmanaged resource.
   private IntPtr handle;
   // Other managed resource this class uses.
   private Component Components;
   // Track whether Dispose has been called.
   private bool disposed = false;

   // Constructor for the BaseResource object.
   public BaseResource()
   {
      // Insert appropriate constructor code here.
   }

   // Implement IDisposable.
   // Do not make this method virtual.
   // A derived class should not be able to override this method.
   public void Dispose()
   {
      Dispose(true);
      // Take yourself off the Finalization queue 
      // to prevent finalization code for this object
      // from executing a second time.
      GC.SuppressFinalize(this);
   }

   // Dispose(bool disposing) executes in two distinct scenarios.
   // If disposing equals true, the method has been called directly
   // or indirectly by a user's code. Managed and unmanaged resources
   // can be disposed.
   // If disposing equals false, the method has been called by the 
   // runtime from inside the finalizer and you should not reference 
   // other objects. Only unmanaged resources can be disposed.
   protected virtual void Dispose(bool disposing)
   {
      // Check to see if Dispose has already been called.
      if(!this.disposed)
      {
         // If disposing equals true, dispose all managed 
         // and unmanaged resources.
         if(disposing)
         {
            // Dispose managed resources.
            Components.Dispose();
         }
         // Release unmanaged resources. If disposing is false, 
         // only the following code is executed.
         CloseHandle(handle);
         handle = IntPtr.Zero;
         // Note that this is not thread safe.
         // Another thread could start disposing the object
         // after the managed resources are disposed,
         // but before the disposed flag is set to true.
         // If thread safety is necessary, it must be
         // implemented by the client.

      }
      disposed = true;         
   }

   // Use C# destructor syntax for finalization code.
   // This destructor will run only if the Dispose method 
   // does not get called.
   // It gives your base class the opportunity to finalize.
   // Do not provide destructors in types derived from this class.
   ~BaseResource()      
   {
      // Do not re-create Dispose clean-up code here.
      // Calling Dispose(false) is optimal in terms of
      // readability and maintainability.
      Dispose(false);
   }

   // Allow your Dispose method to be called multiple times,
   // but throw an exception if the object has been disposed.
   // Whenever you do something with this class, 
   // check to see if it has been disposed.
   public void DoSomething()
   {
      if(this.disposed)
      {
         throw new ObjectDisposedException();
      }
   }
}

// Design pattern for a derived class.
// Note that this derived class inherently implements the 
// IDisposable interface because it is implemented in the base class.
public class MyResourceWrapper: BaseResource
{
   // A managed resource that you add in this derived class.
   private ManagedResource addedManaged;
   // A native unmanaged resource that you add in this derived class.
   private NativeResource addedNative;
   private bool disposed = false;

  // Constructor for this object.
   public MyResourceWrapper()
   {
      // Insert appropriate constructor code here.
   }

   protected override void Dispose(bool disposing)
   {
      if(!this.disposed)
      {
         try
         {
            if(disposing)
            {
               // Release the managed resources you added in
               // this derived class here.
               addedManaged.Dispose();         
            }
            // Release the native unmanaged resources you added
            // in this derived class here.
            CloseHandle(addedNative);
            this.disposed = true;
         }
         finally
         {
            // Call Dispose on your base class.
            base.Dispose(disposing);
         }
      }
   }
}

// This derived class does not have a Finalize method
// or a Dispose method without parameters because it inherits 
// them from the base class.

Now...I read through that example code...but I have absolutely no clue what it does, how to use it or where to put code like that. I abhor copying and pasting code into my applications...I refuse to do it, especially if I have no idea what I'm looking at.

My question is...is it necessary for me to create something like the example above to remove unmanaged resources like SqlConnection object resources?

Because honestly...I wouldn't have the first clue where to begin or what to do if I had to implement something like that.

Because my application can interface with Access database files or SQL Servers (based on what a user selects in the settings) I use connections on many occasions.

My code to get a list of databases from a SQL server is this:

if (Connection is SqlConnection)
            {
                //these types of connections can have many databases
                //cast our connection
                SqlConnection ActiveConnection = (SqlConnection)Connection;

                //open the connection
                ActiveConnection.Open();

                //create our data table and get the list of table names
                DataTable CatalogNames = ActiveConnection.GetSchema("Databases");

                //close the connection
                ActiveConnection.Close();

                //return our data set
                return CatalogNames;
            }

I don't define any Dispose() methods or even implement it on the connection object. If I change nothing else in my application and just use ((IDisposable)ActiveConnection).Dispose(); right after ActiveConnection.Close(); will that dispose of any unmanaged resources or do I need to go through the headache and nightmare of figuring out that example above?

No, you don't have to define a Dispose() method for SqlConnection (or any other object that implements IDisposable), you just have to call it when you are done using that object.

The only time you need to create a Dispose() method is when *you* write the code for a class that has an unmanaged resource. Then you'd need all the stuff from that example. I've been doing this a long time now and don't recall every creating a class that needed to implement IDisposable().

BTW, in your code example you call Close(). If you recall from my previous post, Close() calls Dispose(), so you are disposing of the object! :)

Wait a second...I'm confused again (doesn't take much lately it seems)...if calling Close() on the object automatically disposes of it...would this code throw an exception:

if (Connection is SqlConnection)
            {
                //these types of connections can have many databases
                //cast our connection
                SqlConnection ActiveConnection = (SqlConnection)Connection;

                //open the connection
                ActiveConnection.Open();

                //create our data table and get the list of table names
                DataTable CatalogNames = ActiveConnection.GetSchema("Databases");

                //close the connection
                ActiveConnection.Close();

                //re-open the connection
                ActiveConnection.Open();

                //create our data table and get the list of table names
                DataTable CatalogNamesAgain = ActiveConnection.GetSchema("Databases");

                //close the connection
                ActiveConnection.Close();

                //return our data set
                return CatalogNames;
            }

Also, I was reading some more on the new .NET framework (v4) and found this which seems to indicate that when you call Close() or even Dispose() on a SqlConnection object, that it in fact is not disposed of, but is placed into a Connection Pool where active connections are stored and managed. Here's what the MSDN has to say about this:

Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.

It does say later on that you can actually remove the connections stored in the pool:

Removing Connections
The connection pooler removes a connection from the pool after it has been idle for a long time, or if the pooler detects that the connection with the server has been severed. Note that a severed connection can be detected only after attempting to communicate with the server. If a connection is found that is no longer connected to the server, it is marked as invalid. Invalid connections are removed from the connection pool only when they are closed or reclaimed.

If a connection exists to a server that has disappeared, this connection can be drawn from the pool even if the connection pooler has not detected the severed connection and marked it as invalid. This is the case because the overhead of checking that the connection is still valid would eliminate the benefits of having a pooler by causing another round trip to the server to occur. When this occurs, the first attempt to use the connection will detect that the connection has been severed, and an exception is thrown.

Clearing the Pool
ADO.NET 2.0 introduced two new methods to clear the pool: ClearAllPools and ClearPool. ClearAllPools clears the connection pools for a given provider, and ClearPool clears the connection pool that is associated with a specific connection. If there are connections being used at the time of the call, they are marked appropriately. When they are closed, they are discarded instead of being returned to the pool.

Very interesting...

Oh yea...anyway I suppose this thread is answered. Thanks momerath and embooglement!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.