locked
When do I need to incorporate Dispose into my code?

    Question

  • I'm trying to understand (a) if I ever need to implement Dispose in my classes and (b) if I do, when do I?

    Part of the reason for asking is because I have implemented Dispose in some of my classes, because I wanted to ensure that collections of items were being correctly cleaned up when I didn't need them any longer, but navigating away from pages that results in a lot of items being disposed is causing the app to "lock up" for some time.

    What is the best practice guidance and advice, please? From what I've read, it looks like Store apps *don't* generally need to Dispose, even though they are built on top of .NET and .NET *does* need Dispose.

    Thanks.

    Wednesday, February 4, 2015 5:58 PM

Answers

  • Dispose is orthogonal to garbage collection and isn't directly related to memory.

    The garbage collector handles managed memory and will automatically collect any objects which are unreferenced. Your code just needs to make sure it doesn't leak references to objects that it no longer needs.

    Dispose is used to handle unmanaged resources such as file handles, which the garbage collector doesn't know about. If you leave a file handle open until the garbage collector collects the object holding it then it may never get collected. The garbage collector is lazy and won't collect the memory until it's needed. Dispose will close the handle immediately.

    This is exactly the same for Windows Store apps in .Net as it is for desktop apps in .Net.

    I think where you say ".Net *does* need Dispose" is WinForms specific rather than .Net. The WinForms library is a slim wrapper around native window handles and so WinForms controls require Dispose to take care of the unmanaged HWNDs. If you use a fully .Net toolkit (such as WPF) or a modern projection (such as Windows Store) then fewer Dispose calls will be needed.

    Thursday, February 5, 2015 6:59 PM
    Owner
  • Your first case is a static event, so you'll need to remove it explicitly.

    The second case doesn't need to be explicitly disposed (and isn't in the default templates that use it)

    See the Removing event handlers in code section at the end of Adding event handlers in code for a list of the scenarios where you do need to explicitly remove event handlers.

    Wednesday, February 11, 2015 2:44 AM
    Owner

All replies

  • Hi Philip,

    Usually, you must implement Dispose (from IDisposable) when you own unmanaged/IDisposable objects in your class.

    Other resources are managed/released by garbage collector, you should *not* release them on your own.

    What type of Collection/Items do you refer?

    See https://msdn.microsoft.com/en-us/library/system.idisposable%28v=vs.110%29.aspx for an explanation of Dispose method.

    Wednesday, February 4, 2015 6:46 PM
  • Thanks for your reply.

    There are two reasons why I've been using Dispose:

    1. When some of my classes are constructed, they hook onto event handlers. The Dispose takes care of unhooking from the event handlers.

    2. I've been explicitly removing instances from collections when I have finished with a collection in order to try to make sure that I don't have any memory leaks.

    I've gone through my code to change Dispose() to NoLongerInUse() so that I can still explicitly unhook from the event handlers when I know an instance isn't needed any longer. I'm not sure if there is an automatic solution to that? I didn't want GC to *not* get rid of a resource because it was still hooked up.

    I'm also not sure if I need to explicitly clear a collection. Do I need to do that, or just set the collection to null?

    Thanks.

    Thursday, February 5, 2015 10:28 AM
  • Unregistering from Events is definitely something you should do if you register to them directly. An event registration means that the object of the event still holds a reference to your object which in turn prevents garbage collection of that object.

    If you have a collection of objects and set the reference to that collection to null and there are no other references to that collection the Garbage Collector will take care of it itself. Basically - the GC checks wether a reference is still alive by checking wether it's still reachable via references from the application root. If it is, it's kept alive - if it's not, it's collected. So in your example it would first find that the collection is not reachable and can be collected and then that the objects contained in the collection also aren't reachable.

    Thursday, February 5, 2015 11:10 AM
  • Just to make sure I've properly understood your advice:

    1. I do need to explicitly unregister from events but

    2. I don't need to explicitly remove instances from a collection; I can just set the reference to null.

    Many thanks.

    Thursday, February 5, 2015 11:12 AM
  • 1. I do need to explicitly unregister from events but

    It's not usually necessary to remove event handlers in code, even if you added them in code. The object lifetime behavior for most Windows Runtime objects such as pages and controls will destroy the objects when they are disconnected from the main Window and its visual tree, and any delegate references are destroyed too. .NET does this through garbage collection and Windows Runtime with C++/CX uses weak references by default.

    There are some rare cases where you do want to remove event handlers explicitly. These include:

    Handlers you added for static events, which can't get garbage-collected in a conventional way. Examples of static events in the Windows Runtime API are the events of the CompositionTarget and Clipboard classes.
    Test code where you want the timing of handler removal to be immediate, or code where you what to swap old/new event handlers for an event at run time.
    The implementation of a custom remove accessor.
    Custom static events.
    Handlers for page navigations.
    See https://msdn.microsoft.com/en-us/library/hh758286.aspx

    2. I don't need to explicitly remove instances from a collection; I can just set the reference to null.

    You need to set null if your class is still referenced. If there is no references to your class and no other references to this collection, it will be automatically collected by GC.

    This is not available for IDisposable objects on which you should call Dispose on your own

    • Edited by OMAW8 Thursday, February 5, 2015 5:26 PM
    Thursday, February 5, 2015 4:27 PM
  • Dispose is orthogonal to garbage collection and isn't directly related to memory.

    The garbage collector handles managed memory and will automatically collect any objects which are unreferenced. Your code just needs to make sure it doesn't leak references to objects that it no longer needs.

    Dispose is used to handle unmanaged resources such as file handles, which the garbage collector doesn't know about. If you leave a file handle open until the garbage collector collects the object holding it then it may never get collected. The garbage collector is lazy and won't collect the memory until it's needed. Dispose will close the handle immediately.

    This is exactly the same for Windows Store apps in .Net as it is for desktop apps in .Net.

    I think where you say ".Net *does* need Dispose" is WinForms specific rather than .Net. The WinForms library is a slim wrapper around native window handles and so WinForms controls require Dispose to take care of the unmanaged HWNDs. If you use a fully .Net toolkit (such as WPF) or a modern projection (such as Windows Store) then fewer Dispose calls will be needed.

    Thursday, February 5, 2015 6:59 PM
    Owner
  • I need to drill into the whole "do I need to unhook from events" a bit more because I'm getting very confused as to when I need to and when I don't. Here are a couple of examples:

    1. I have a class called RHObjectFile and it defines the following:

    publicstaticeventEventHandlerFileChangedEvent;

    and some other classes (e.g. RHIndividualRecord) where the constructor includes:

    RHObjectFile.FileChangedEvent += HandleFileChangeEvent;

    So, given that arrangement, do I need to unhook from FileChangedEvent in order for GC to realise that an instance of RHIndividualRecord is no longer in use? If GC gets rid of an instance of RHIndividualRecord, does it automatically (magically) unhook from event handlers?

    2. Pages typically have something like the following in their constructor:

    this.navigationHelper = newNavigationHelper(this);

    this.navigationHelper.LoadState += navigationHelper_LoadState;this.navigationHelper.SaveState += navigationHelper_SaveState;

    Again, do I need to unhook from LoadState/SaveState in order to allow GC to clean up the Page instance when it isn't in use any more?

    Thanks.

    Wednesday, February 11, 2015 2:11 AM
  • Your first case is a static event, so you'll need to remove it explicitly.

    The second case doesn't need to be explicitly disposed (and isn't in the default templates that use it)

    See the Removing event handlers in code section at the end of Adding event handlers in code for a list of the scenarios where you do need to explicitly remove event handlers.

    Wednesday, February 11, 2015 2:44 AM
    Owner