locked
Standard Dispose pattern: "managed" vs. "unmanaged" resources in Dispose(bool) - what is a "managed" resource to free when Dispose(true)?

    Question

  • Hello,

    I am trying to implement the standard dispose pattern in my class as follows.

     

     

    namespace MyNamespace
    {
     class MyClass : IDisposable
     {
      private bool alreadyDisposed = false;
    
      private FileStream fs;
      private StreamReader sr;
    
      public MyClass()
      {
       // Open a file...
      }
    
      ~Forecast()
      {
       Dispose(false);
      }
    
      public void Dispose()
      {
       Dispose(true);
       GC.SuppressFinalize(this);
      }
    
      protected virtual void Dispose(bool disposing)
      {
       if (alreadyDisposed) return;
       if (disposing)
       {
        // Free managed resources here.
       }
       // Free unmanaged resources here.
       if (sr != null) sr.Dispose();
       if (fs != null) fs.Dispose();
    
       alreadyDisposed = true;
      }
     }
    }
    
    

     

    I think I put "sr.Dispose()" and "fs.Dispose()" in the right place: in the "Free unmanaged resources here" section.

    Please let me know if I am mistaken.

     

    My main question is, what kind of code would go in the "Free managed resources here" section?

    In addition, if someone could give me a concrete example, and explain why it qualifies as a managed resource in this context, that would be fantastic.

     

    Thank you for your time.

    Tuesday, June 29, 2010 1:30 PM

Answers

  • Hello,

    Typically all the code that runs by the CLR is considered managed at least in your perspective, outside to it, you have Win32 API, ActiveX, COM object these are not managed.

    There are few exceptions such as the Marshal class.

     


    Eyal, Regards.

    blog.eyalsh.net
    • Marked as answer by icancode Friday, July 02, 2010 3:41 PM
    Friday, July 02, 2010 6:35 AM

All replies

  • Examples would be closing a file stream, or calling Dispose on members that are themselves disposable.
    http://blog.voidnish.com
    Tuesday, June 29, 2010 2:01 PM
    Moderator
  • To see actual code take a look at any Visual Studio generated Winforms code, and you should see something like this in the Form Dispose implementation:

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }


    http://blog.voidnish.com
    Tuesday, June 29, 2010 2:03 PM
    Moderator
  • A StreamReader, a FileStream are .Net managed objects.

    Unmanaged resources will typically be stored in IntPtr variables.

    Tuesday, June 29, 2010 3:44 PM
  • A StreamReader, a FileStream are .Net managed objects.

    Unmanaged resources will typically be stored in IntPtr variables.


    Yeah but the OP was asking what "managed resources" he should be looking to dispose there.
    http://blog.voidnish.com
    Tuesday, June 29, 2010 3:54 PM
    Moderator
  • The OP also said:

    "I think I put "sr.Dispose()" and "fs.Dispose()" in the right place: in the "Free unmanaged resources here" section.

    Please let me know if I am mistaken."

    Tuesday, June 29, 2010 4:08 PM
  • The OP also said:

    "I think I put "sr.Dispose()" and "fs.Dispose()" in the right place: in the "Free unmanaged resources here" section.

    Please let me know if I am mistaken."


    Ok, I thought your reply was to my post since there was no quote and your reply was immediately beneath mine. I, btw, was replying to the OP's question:

    "My main question is, what kind of code would go in the "Free managed resources here" section?"


    http://blog.voidnish.com
    Tuesday, June 29, 2010 6:34 PM
    Moderator
  • OK, so I didn't have my calls to "Dispose()" in the right place after all!

    Thank you for pointing that out.

     

    Perhaps this is the question that I ought to be asking:

    Why is there a "Dispose(bool)" in the first place?

    If the bool is "True", then we know that we have arrived from client code which explicitly called "Dispose()".

    If the bool is "False", then we know that we have arrived from the finalizer.

    But what difference does it make?

    Clearly I am missing something important.

     

    Tuesday, June 29, 2010 7:25 PM
  • The difference is that if the call originated from the finalizer, then the managed resources may nor may not have been finalized already. So you should only free the unmanaged resources. Whereas if the call originated from a manual call to Dispose, it's been called deterministically (so to speak) and thus it's safe to free/dispose any managed resources that need disposing.
    http://blog.voidnish.com
    Tuesday, June 29, 2010 7:33 PM
    Moderator
  • Perhaps in most cases I will find myself calling "Dispose()" on member objects in the "Free managed resources here" section...

     

    Can you help me with this question?

    What is the definition of an "unmanaged resource" in this context?

    What is it that tells you. "I need to dispose of this in the 'unmanaged resource' section, NOT the managed resource section (of Dispose(bool))"?

    • Edited by icancode Tuesday, June 29, 2010 7:45 PM
    Tuesday, June 29, 2010 7:34 PM
  • An example of an unmanaged resource would be some memory that you created using Marshal.AllocHGlobal. You need to free this memory using FreeHGlobal to avoid a memory leak. That's just an example.
    http://blog.voidnish.com
    Tuesday, June 29, 2010 7:36 PM
    Moderator
  • The difference is that if the call originated from the finalizer, then the managed resources may nor may not have been finalized already. So you should only free the unmanaged resources. Whereas if the call originated from a manual call to Dispose, it's been called deterministically (so to speak) and thus it's safe to free/dispose any managed resources that need disposing.
    http://blog.voidnish.com

    Nishant, you sure are quick to reply! Thank you.

    In the case that we have arrived at "Dispose(bool)" from the finalizer,

    is there no way to tell if something has been finalized or not?

    Since it is possible that the managed resources have NOT been finalized yet, isn't it bad to just "let them go"?

    Tuesday, June 29, 2010 7:44 PM
  • Yes, that's correct. There's no way to predict the order of finalization.

    And you are not "letting them go". Since the finalizer is claiming this object, it's safe to assume that any associated objects have already been finalized or will be finalized soon, perhaps in that very same GC cycle.


    http://blog.voidnish.com
    Tuesday, June 29, 2010 7:53 PM
    Moderator
  • Yes, that's correct. There's no way to predict the order of finalization.

    And you are not "letting them go". Since the finalizer is claiming this object, it's safe to assume that any associated objects have already been finalized or will be finalized soon, perhaps in that very same GC cycle.


    http://blog.voidnish.com

    Nishant, thanks again for all your help.

    I've been thinking about all this and I must say, this talk of "unmanaged" and "managed" really got me confused... and I think I know why.

    When I started reading about "IDisposable," I learned that "Dispose()" is a mechanism provided so that you can explicitly free UNMANAGED resources such as file handles and database connections. In retrospect I think that the term "unmanaged" is used  here because these things are not managed by the GC (which indeed knows nothing about them).

    I went on to learn about how there is an accepted "standard dispose pattern" for types that contain unmanaged resources (say, for example, a "SqlConnection") as members. This dispose pattern makes a distinction between "unmanaged" and "managed" resources. Check out this code from MSDN http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize(v=VS.71).aspx:

     

    private 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.
         component.Dispose();
        }
       
        // Call the appropriate methods to clean up 
        // unmanaged resources here.
        // If disposing is false, 
        // only the following code is executed.
        CloseHandle(handle);
        handle = IntPtr.Zero;   
       }

     

    Here what the comment calls "managed resources" is actually referring to the "UNmanaged resources" that I first described: file handle, database connections, etc.

    That's quite confusing, don't you think?

    Perhaps... what is considered to be an "unmanaged  resource" inside "Dispose(bool)" is anything that does not have its own finalizer. Do you think that is correct?

    Wednesday, June 30, 2010 2:49 AM
  • What is called managed resources in that sample is actually referring to managed resources.

     

    A FileStream is a managed resource. The file handle it contains is an unmanaged resource. You don't have to clean up the FileStream in the "unmanaged resources" part. FileStream will clean up the file handle in its own Dispose method.

    On the other hand, if you use the kernel32.dll CreateFile function, you get an IntPtr. That's an unmanaged resource.

    Wednesday, June 30, 2010 3:48 PM
  • What is called managed resources in that sample is actually referring to managed resources.

     

    A FileStream is a managed resource. The file handle it contains is an unmanaged resource. You don't have to clean up the FileStream in the "unmanaged resources" part. FileStream will clean up the file handle in its own Dispose method.

    On the other hand, if you use the kernel32.dll CreateFile function, you get an IntPtr. That's an unmanaged resource.


    Hi Louis,

    It seems the Int is managed, the "object" it's point to is unmanaged.


    Best regards,
    Harry Zhu
    - MSFT MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com
    Friday, July 02, 2010 3:16 AM
  • Yes, that's correct. There's no way to predict the order of finalization.

    And you are not "letting them go". Since the finalizer is claiming this object, it's safe to assume that any associated objects have already been finalized or will be finalized soon, perhaps in that very same GC cycle.


    http://blog.voidnish.com

    Nishant, thanks again for all your help.

    I've been thinking about all this and I must say, this talk of "unmanaged" and "managed" really got me confused... and I think I know why.

    When I started reading about "IDisposable," I learned that "Dispose()" is a mechanism provided so that you can explicitly free UNMANAGED resources such as file handles and database connections. In retrospect I think that the term "unmanaged" is used  here because these things are not managed by the GC (which indeed knows nothing about them).

    I went on to learn about how there is an accepted "standard dispose pattern" for types that contain unmanaged resources (say, for example, a "SqlConnection") as members. This dispose pattern makes a distinction between "unmanaged" and "managed" resources. Check out this code from MSDN http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize(v=VS.71).aspx:

     

    private 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.
    
       component.Dispose();
    
      }
    
      
    
      // Call the appropriate methods to clean up 
    
      // unmanaged resources here.
    
      // If disposing is false, 
    
      // only the following code is executed.
    
      CloseHandle(handle);
    
      handle = IntPtr.Zero;  
    
      }
    
    

     

    Here what the comment calls "managed resources" is actually referring to the "UNmanaged resources" that I first described: file handle, database connections, etc.

    That's quite confusing, don't you think?

    Perhaps... what is considered to be an "unmanaged  resource" inside "Dispose(bool)" is anything that does not have its own finalizer. Do you think that is correct?


    Hi,

    Could you please be more clear about the "managed resources"? I think both instance of MyResource and component are managed.

    Please notice the defination of handle, it's pointing to an external unmaged resource. I'd see the IntPtr as managed variable.

    // Pointer to an external unmanaged resource.
            private IntPtr handle;

     


    Best regards,
    Harry Zhu
    - MSFT MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com
    Friday, July 02, 2010 3:21 AM
  • Hello,

    Typically all the code that runs by the CLR is considered managed at least in your perspective, outside to it, you have Win32 API, ActiveX, COM object these are not managed.

    There are few exceptions such as the Marshal class.

     


    Eyal, Regards.

    blog.eyalsh.net
    • Marked as answer by icancode Friday, July 02, 2010 3:41 PM
    Friday, July 02, 2010 6:35 AM
  • What is called managed resources in that sample is actually referring to managed resources.

     

    A FileStream is a managed resource. The file handle it contains is an unmanaged resource. You don't have to clean up the FileStream in the "unmanaged resources" part. FileStream will clean up the file handle in its own Dispose method.

    On the other hand, if you use the kernel32.dll CreateFile function, you get an IntPtr. That's an unmanaged resource.


    Hi Louis,

    It seems the Int is managed, the "object" it's point to is unmanaged.


    Best regards,
    Harry Zhu
    - MSFT MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com

    In an earlier post, Lois said,

    "Unmanaged resources will typically be stored in IntPtr variables."

    Friday, July 02, 2010 3:37 PM
  • Yes, that's correct. There's no way to predict the order of finalization.

    And you are not "letting them go". Since the finalizer is claiming this object, it's safe to assume that any associated objects have already been finalized or will be finalized soon, perhaps in that very same GC cycle.


    http://blog.voidnish.com

    Nishant, thanks again for all your help.

    I've been thinking about all this and I must say, this talk of "unmanaged" and "managed" really got me confused... and I think I know why.

    When I started reading about "IDisposable," I learned that "Dispose()" is a mechanism provided so that you can explicitly free UNMANAGED resources such as file handles and database connections. In retrospect I think that the term "unmanaged" is used  here because these things are not managed by the GC (which indeed knows nothing about them).

    I went on to learn about how there is an accepted "standard dispose pattern" for types that contain unmanaged resources (say, for example, a "SqlConnection") as members. This dispose pattern makes a distinction between "unmanaged" and "managed" resources. Check out this code from MSDN http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize(v=VS.71).aspx:

     

    private 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.
    
      component.Dispose();
    
     }
    
     
    
     // Call the appropriate methods to clean up 
    
     // unmanaged resources here.
    
     // If disposing is false, 
    
     // only the following code is executed.
    
     CloseHandle(handle);
    
     handle = IntPtr.Zero; 
    
     }
    
    

     

    Here what the comment calls "managed resources" is actually referring to the "UNmanaged resources" that I first described: file handle, database connections, etc.

    That's quite confusing, don't you think?

    Perhaps... what is considered to be an "unmanaged  resource" inside "Dispose(bool)" is anything that does not have its own finalizer. Do you think that is correct?


    Hi,

    Could you please be more clear about the "managed resources"? I think both instance of MyResource and component are managed.

    Please notice the defination of handle, it's pointing to an external unmaged resource. I'd see the IntPtr as managed variable.

    // Pointer to an external unmanaged resource.
            private IntPtr handle;

     


    Best regards,
    Harry Zhu
    - MSFT MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com

     

    I'm not sure what you mean by "MyResource".

    As I understand it, "component" is indeed managed.

    There are some good definitions of managed vs. unmanaged in this thread; see Eyal-Shilony's post, for example.

    Friday, July 02, 2010 3:41 PM

  • Hi Louis,

    It seems the Int is managed, the "object" it's point to is unmanaged.

    In an earlier post, Lois said,

    "Unmanaged resources will typically be stored in IntPtr variables."


    An IntPtr is nothing more than the managed counterpart of an handle. It could be a pointer to an unmanaged resource or any handle returned by the system.
    Friday, July 02, 2010 4:37 PM