Watch out for those WaitOne() overloads (when you need backwards compatibility)

Recently I was writing some new functionality that ran work on background threads.  The functionality isn’t that important but one of the classes I was using to get the correct behavior was AutoResetEvent.  Specifically the AutoResetEvent.WaitOne() method.

Since I really don’t use this class very often, I relied on intellisense to give the list of method overloads and I selected the WaitOne(Int32) overload which allows the thread to wait a given number of milliseconds unless signaled first.  My compile worked and the functionality ran properly in Visual Studio 2008 SP1.  Since I share the of the same code base when my product is installed in VS2005, I jumped over and the product compiled and ran perfectly there as well.

I forgot all about this until I was doing the final testing in preparation for a new release.  The first few VPC images took the installation and ran fine.  However, when I ran the installation in a VPC image that had a clean installation of VS2005 SP1 and nothing else, the product did not work properly.  I was puzzled until I enabled logging and found that I was getting a MissingMethodException on the WaitOne(Int32) method.

I’ll spare you the details of the agony but I thought about this for a while and decided to try installing the .NET 3.5 SP1 framework in this VM and, low and behold, the problem vanished.

It turns out this method overload was introduced in .NET 3.5 SP1 but because System.Threading resides in mscorlib and there is only a 2.0 version of that assembly, any .NET 2.0 application (which in my case was the VS2005 package) is able to compile against it and run as long as the SP1 version of .NET 3.5 is present on the machine.

The solution was to use the WaitOne(Int32, bool) passing false to the second parameter which gives the same functionality.

I’ll be watching for this type of thing a little closer from now on.