3

I'm looking for advice on how and when to implement the dispose pattern.
I've read the MSDN article on how to implement the Dispose() pattern. It makes sense. I implemented it in my class, but it doesn't seem to make a difference on memory usage.

Bit of background, I'm building a 2d top down game engine. I have units called Gatherer, which inherits from Actor (A basic class for drawing the sprite and tracking the viewplane), and they're simple sprites that go out and do things. They disappear after 5 game rounds of play.

I use a list to track the Gatherers, implemented like this:

 List<Gatherer> gatherList = new List<Gatherer>();

Then I prune the list like this inside the game engine:

public void pruneDeadFollowers()
{
for (int i = gatherList.Count-1; i> -1; i--)            
    {
        if (gatherList[i].timeToDie) //Bool to check if unit needs to be removed this round.
        {                    
            this.dropActor(gatherList[i]); //Calls method that unsubscribes the object from triggered events.
            gatherList[i].Dispose();  //Is this needed?
            gatherList.RemoveAt(i); //Remove from list.
        }
    }
}

The Gatherer object is pretty simple. It has mostly managed objects.
It has lots of Int fields, a couple of List, a couple of Point (From Monogame), a couple of Bool objects and several Static Int. I also have Random r; created at runtime, but that doesn't seem to have a Dispose method. The only unmanaged objects I have are 2 Texture2D objects. public Texture2D glowTexture; public Texture2D texImage;

In my dispose, I think I only need to dispose of the textures.
The one problem is that if I actually call texImage.Dispose(); it destroys the texture for the other units still alive. I think I can just make the texture Null instead, which doesn't affect the existing units.

I have this dispose: Is this sufficient? If not, how can I verify that's working as needed?

 public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

// Protected implementation of Dispose pattern. 
protected virtual void Dispose(bool disposing)
{
    if (disposed)
        return;

    if (disposing)
    {                        
        glowTexture = null;
        texImage = null;
    }

    disposed = true;
}
EtanSivad
  • 487
  • 8
  • 16
  • Side note, you don't need `GC.SuppressFinalize(this);` unless you actually have a finalizer in your object. That's only for when you implement a `~MyObject() { Dispose(false); }`. If you implement it (that's the whole point of the pattern you are following), the `if(disposing){}` part should only be done on **managed** resources, not on unmanaged ones (those should be freed by the finalizer if you forget to call `Dispose()`). Unmanaged resources should always free disregarding the parameter. – Jcl Jan 22 '15 at 18:04
  • The `disposing` parameter should really be called `amIBeingCalledDeterministically` :-) – Jcl Jan 22 '15 at 18:11

1 Answers1

4

Your implementation is valid, but not really sufficient.

Dispose is used to release unmanaged resources, as you have found. Your initial implementation (where you disposed the textures after using them) was correct.

Except you are sharing those resources among multiple objects, so you don't want the objects using the textures to control their lifetime.

I would follow the pattern in XNA. Whoever loads the content also needs to unload it. In your case, whoever creates the textures (and thus the child objects) should dispose them when it is disposed. The child objects using the textures actually don't need to implement IDisposable at all from what I can see.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117