tags:

views:

344

answers:

6

Hi,

I have query regarding the disposing of an object. The scenario is as follows.

In a Desktop Appication, developed in C#, I have a function in which a object in created like this.

namespace Class 1
{
    variables section;
    ....
    ....

    Function1()
    {
         local variables;
         try
         {
              Object1 obj = new Object1();
              ....
              ....
              if(true)
              {
                  ....
              }
              else
              {
                   **obj.Dispose();**
              }
          }
          catch()
          {}
          finally
          {}
     }
}

The object is not disposed when the else part is executed. The msdn link for this is

http://msdn.microsoft.com/en-us/library/system.componentmodel.component.dispose(VS.90).aspx

according to which the component should realase all the resources used by it.

I would like to know, why the object is not disposed.

Thank you.

Pavan Navali.

A: 

Is the "else part" executed in the first place? You say that the "if part" is always true

ThanosPapathanasiou
The else part will be executed. Rewriting the if condition as follows.... if(somecondition) { } .... ....
Pavan Navali
+2  A: 

Without seeing your code it's hard to say for sure, but you may be mistaking 'Dispose' with a different concept like a destructor in c++ or delete/free

John Weldon
I also posted the link of a msdn article, with the question, in which, the description of Dispose() function saysReleases all resources used by the Component.
Pavan Navali
+3  A: 

Since it appears that your custom object inherits from System.ComponentModel.Component, you will need to override Dispose(bool) to dispose of your object's resources. Although your object inherits from System.ComponentModel.Component (which has a Dispose method), your object's custom resources will not be disposed of unless you code the dispose method to do so. (It's not an automatic thing you get by inheriting from System.ComponentModel.Component. Only resources known to the System.ComponentModel.Component base class will be disposed of.)

Try something like this in your class:

protected override void Dispose(bool disposing)
{
    // release your resources here
}

We don't know what resources are on your object are not being disposed of, but whatever the object, the dispose method must be coded so that it releases the resources. If an object's resource is not disposed of in the dispose method, it won't be disposed when you dispose it.

For example:

ExpensiveResource myExpensiveResource1;
ExpensiveResource myExpensiveResource2;

void Dispose()
{
    // release the resources
    myExpensiveResource1.Dispose();

    // since there is no call to dispose of myExpensiveResource2, it is not disposed of
}
Zach Johnson
A: 

You should refactor your Code to look like this:

Function1()
{
  local variables;
  try
  {
     using (Object1 obj = new Object1())
     {
       ....
       ....
       if(true)
       {
         ....
       }
     }
  }
  catch() // I hope you don't use try-catch like this in real code
  {}      // I hope you don't use try-catch like this in real code
  finally // I hope you don't use try-catch like this in real code
  {}      // I hope you don't use try-catch like this in real code
}

The using statement makes sure the Dispose of the obj is always called when it leaves scope.

dbemerlin
+3  A: 

IDisposable.Dispose is simply a method that a class can chose to implement. The contents of that method is entirely determined by the class' designer. In order to understand exeactly what is going wrong there are a number of terms that you should understand when it comes to disposing/finalizing an object.

Disposing

Disposing an object means to simply call the object's Dispose method. It is a convention that the object releases its unmanaged resources(files, network handles, streams) from this function. If you keep a reference to the object after calling Dispose the object will still be mostly functional, unless you try to access the resources that have been released in Dispose method.

Finalizing

An object is finalized when the .NET CLR Finalizer decides that there are no more objects using this particular object and the memory taken up by it can now be reclaimed. A programmer has no direct control over forcing the runtime to declare an object "dead". You can force the garbage collector to run, but even then it's not recommended (i.e. you REALLY need to know what you are doing to be dabbling with GC).

How do I know that Dispose has run?

Well, the best way is to set the breakpoint in the Dispose method. If you haven't got the source code, you can use this method.

Can I tell that Dispose has run by seeing the memory consumed by the process go down?

No. After Dispose runs the CLR object is still around. Memory is released to managed memory pool after the object is finalized. If you know exactly what kind of resource it is you can use third party OS tools like Process Explorer to, for example, see if the process released a file handle. Even then, there may be a lag between the process releasing the handle and the OS thinking it's released.

How do I know that the object has been finalized?

Again, by setting a breakpoint in the finalizer or by running a memory profiler. Even when the finalizer runs, it is quite likely (in fact most certainly) the memory is not released to the operating system. It stays in the managed memory pool and the CLR runtime can chose to utilise it later.

Even still, when the memory is released to the OS, the process will look like using that memory. It would be up to the OS to take that memory when it feels like it needs it.

If you try to figure out what your app is doing by looking at the amount of memory it consumes in the Process Manager, I can guarantee you will go insane trying to analyse. In fact trying to do that is on par with trying to use regular expressions to parse HTML.

Conclusion

None of this really answers you question. So, here is a checklist to figure out you problem, as we havn't got much to go on with:

  1. How do you know that Dispose hasn't run? Have you debugged the app and set the breakpoint on this line: **obj.Dispose();**?
  2. If the breakpoint gets hit have you stepped through the code to figure out what is happening?
  3. Can you clarify what you mean by Object not disposed?
Igor Zevaka
I have debugged the code and stepped through the code after the break point on the line obj.Dispose() was hit. the following code is executedprotected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); }By Object not disposed, I mean I can still access the object like this.... if(SomeCondition) { } else { obj.Dispose(); } string s = obj.Fname // Fname is a member of the object obj... –
Pavan Navali
That's expected behaviour. As soon as there are no objects holding a reference to the disposed object it will go away. In .NET you are not meant to worry about these things.
Igor Zevaka
+2  A: 

You're conflating the concept of disposal, which in .NET means "the implementation of IDisposable and consequently a Dispose () method", and which guarantees that unmanaged resources are freed, and the concept of garbage collection, which is handled by the runtime and means "the freeing of memory allocated to objects". While you maintain a reference to any object, the garbage collector won't touch it - so the memory allocated by the object isn't freed until this happens.

These are easy concepts to confuse for two reasons:

First, its generally good practice to work with IDisposable objects through the using statement, as follows:

using (IDisposable d = new MyDisposableObject ()) {
    // do whatever you need d for
}

which ensures that d is disposed of when you exit the using block; but it also restricts the scope of d to the block, meaning that once execution exists the block, the object is also free to be garbage collected (not that it necessarily will be immediately, but thats neither here nor their since your code no longer maintains a reference to it). So in this (extremely common, and should probably be considered standard) idiom, disposal occurs at the same time as eliminating the references.

Secondly, good practice for classes that directly access unmanaged resources is to implement a finalizer that calls Dispose (). Finalizers run when the object is garbage collected, so you can ensure that you don't ever leave a dangling leak on an unmanaged resource, but if the object is never properly disposed of then you are leaving the decision on when to free the unmanaged resources strictly in the hands of the runtime, which decides when to perform garbage collection only on the basis of memory pressure and has no knowledge or interest in the quantity or type of references to unmanaged resources. So in this case, garbage collection of an object forces the disposal of the unmanaged resources.

In the case when you explicitly call Dispose () on a method, such as in your question (assuming of course that Object1 implements IDisposable), you still maintain the reference to obj, and as a consequence of that can access all of its properties and methods. It is of course perfectly reasonable that those methods or properties require the unmanaged resource which you have already disposed of, in which case a System.ObjectDisposedException may be thrown, or however else the authors of Object1 have chosen to handle that case, but it also perfectly reasonable for them to function as expected if they don't require the resources you've freed.

As an example, look at System.IO.FileStream. Once you've disposed of it, operations such as ReadByte () throw an exception, since theres obviously no access to the file to read from, but calling the property CanRead just returns false, which is valid and expected. (A MemoryStream for example can even still access the data after a Dispose () call, since the (current) implementation uses a buffer managed by the runtime and not anything like a kernel handle).

Matt Enright