Home

James Lao

About

How To Implement IDisposable

I review a lot of C# code and the one thing I see people screw up the most is IDisposable. I think part of the reason is they don’t understand why IDisposable exists. After all, isn’t C# managed?

IDisposable exists to to cleanup unmanaged resources. When I say unmanaged, I mean things like raw file handles or unmanaged memory you might get from calling into unmanaged code. All standard .NET classes are managed so most people never have to worry about this. However, if you have a class that contains another class that implements IDisposable, you should also implement IDisposable. Before we go into why, we need to understand how classes that do contain unmanaged resources are implemented.

When a class contains unmanaged resources, it needs to implement a finalizer (also known as a destructor) that frees unmanaged resources. Finalizers are called before an object is garbage collected. However, when an object has a finalizer, it requires two passes of the garbage collector to be collected instead of one. On the first pass, the GC sees that the object implements a finalizer so it adds it to the finalizer queue. A special thread dequeues and runs the finalizer for each object. Only then can the GC free the object on the second pass. So technically IDisposable is not necessary for everything to be freed properly, but it provides us with two things:

  1. A consistent way to deterministicly cleanup of unmanaged resources.
  2. Avoiding the finalizer queue so the object can be collected in a single GC pass.

The pattern we are told to implement looks like this:

public class A : IDisposable
{
  private bool disposed = false;

  public ~A()
  {
    this.Dispose(false);
  }

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

  protected virtual void Dispose(bool disposing)
  {
    if (this.disposed) return;

    if (disposing)
    {
      // Cleanup managed resources. That is, call
      // Dispose on any IDisposable objects we own.
    }

    // Cleanup unamanaged resources

    this.disposed = true;
  }
}

The first thing to note is that the finalizer calls Dispose(false) and Dispose() calls Dispose(true). When false is passed, we skip cleaning up managed resources. We need to do this because when we are on the finalizer queue, the the managed objects we reference may have already been collected since the order in which objects are finalized is not deterministic.

When Dispose() is called, we pass true to Dispose(bool) so that we dispose of any IDisposable objects we own in addition to freeing any unmanaged resources we own. That is, we free any unmanaged resources we indirectly own in addition to the ones we directly own. We also call GC.SuppressFinalize(this) to tell the GC that it does not need to call the finalizer and it is safe to collect the object on the first pass.

We make Dispose(bool) protected so that a derived class can call it. If we were to define a class B that derives from A, it would implement IDisposable in a similar fashion. The only difference is it would make an additional base.Dispose(disposing) call at the end of its Dispose(bool) implementation. If we make class A sealed then we can make Dispose(bool) private.

If our class does not own any unmanaged resources and only other IDisposable objects (which is usually the case), we don’t need the finalizer or the call to GC.SuppressFinalize(this). However, we should still implement a separate protected Dispose(bool) method so that derived classes can follow the above pattern. The only case where we can eschew the separate Dispose(bool) method is if our class is both sealed and has no unmanaged resources.

Ninjas, Space Horror, and Crafting

One of the perks of working at Xbox is I can get pretty much any game I want. Unfortunately I don’t have time to play every game I want, so I have pick and choose. These are the favorite games I played since I started working at Xbox.

Mark of the Ninja

I played the crap out of this game. I first saw Mark of the Ninja when I was wandering around the indie games section at PAX. There was no line so I sat down to try the game on a whim and I walked a way with a huge grin on my face. This game is awesome. The art style is unique and the animations are fluid. But where this game really shines is gameplay. They really nailed it. You start out with a fairly limited set of abilities, but as you progress you unlock more abilities which let you take advantage of every aspect of your environment like dangling on a chain from ledges and assassinating your targets from behind closed doors. You can tell lot of thought went into designing the ninja abilities and the levels to work together.

Dead Space

I refused to play Dead Space at night for the longest time because it was too scary. I’m not a huge fan of the horror genre, but this game adds a twist to the shooting genre dominated by Call of Duty and all its clones. Head shots don’t do much because it turns out corpses reanimated by an extraterrestrial infection don’t need heads to kill you. To take them down you have to systematically dismember them using a variety of space mining tools. Everything in this game adds to the sense of horror as you make your way through the ship. Strange noises following you around and great lighting effects make the absence of necromorphs more terrifying than when you are fighting them. I’m surprised how much I enjoyed this game, but Dead Space is an awesome experience.

Minecraft

Productivity on my team tanked the week Minecraft was released on Xbox LIVE Arcade. People say creativity benefits when you add constraints. Minecraft is a perfect example of that. All there is to do is mine blocks and build things with blocks and despite how blocky everything is, you can still create amazing things in this game.

Bioshock Infinite

BioShock Infinite is insanely great. The story is amazing. The characters are unforgettable. The gameplay is a blast. Sorry, am I gushing?

The first two thirds of the story is pretty standard. The gameplay really shines here though. The combination of shooting, vigors, and the skyhook creates a unique combat experience. You might be tempted to stand back with sniper rifle and just pick off enemies one by one with well placed head shots, but you’d lose out on everything that makes the gameplay in Infinite different from other first person shooters. Vigors like Bucking Bronco are invaluable when you there are ten enemies running at you with guns blazing. Undertow can be used to reel in those pesky snipers. If things get too dicy you can hop on a skyline and zip away. Using all your abilities together is necessary to beating some of the bigger enemies like the Handyman. You won’t be doing all of this alone though. Elizabeth has got your back.

Usually AI buddies are pretty dim, but Elizabeth is the best AI companion I have ever seen. She is never in your way and is there when you need her most in a big fight. She will throw you supplies when you are running low and she will revive you when you’re down. She is aware of the world around her as she points out interesting things in the environment and items you should pick up. If you sit back she will walk around the world examining objects with youthful curiosity that makes her so much more believable. Booker becomes attached to Elizabeth. A lot of work went into making the player feel the same way Booker does, and it worked, because I did.

The last third of the game is where the story shines. Everything you thought you knew about Elizabeth gets turned upside down. Everything gets a little stranger and the ending will blow your mind. Audio recordings add a lot of detail to the story, which is unfortunate in some ways because you have to actively search for them. But it is definitely worth looking for all of the recordings because the story is so complex I think it would be hard to understand everything without them. Trust me, it’s worth it. Everything comes together in the last thirty minutes of the game. The final realization hit me like a ton of bricks and I was emotionally drained when the credits started rolling.

There are great games and then there are insanely great games. BioShock Infinite is the latter. Few games manage to tune their gameplay just right. Fewer still manage to tell such a compelling story in the middle of all of it.