HashSet Deserialization Oddities

So, yesterday was a fun day.  I spent all day trying to debug a state in which one of your QA web servers' worker processes would go into an infinite loop and peg a core on the CPU.  After many hours, and finally installing the remote debugging tools on the server, I eventually found the problem - removing an item from a HashSet. ?!?

So let me set the scenario up.  I have a website that runs in a farm, so I utilize SQL for state management.  As you probably already know, all objects that go into state are binary serialized, forwarded to the SQL server, and then fetched and deserialized upon request after the next page load.  

I have a state object that is placed in to session state.  It contains some state that is a HashSet<Guid> object.  The first time this object is put into state, it is empty.  I then retrieve it and place a few guids into it.  This is where it gets odd.  If i browse the object after I add the guids to it, it appears that some of them go in to the set as Empty Guids, regardless of their value when i actually added them.  This is after the set has been deserialized from state empty, then values added to it. 

Interestingly enough, it actually adds multiple duplicate keys to the set, which is natively not permissable.  Under normal circumstances, were I to add Guid.Empty into a hashset 3 times, it will only appear in the set once.  Not in this case.  It appears that the set is checking for uniqueness with the real value being passed in, detects that the value is unique, yet after the value is added it is actually added as Guid.Empty.  So this would be crazy enough... but thats not where the story ends. 

Now, a few methods away I am tearing through the values in the set, and removing ones that meet a certain condition.  Except that since I am receiving empty guids back for most of the items i put in the set, these are always meeting my removal condition.  Aside from the craziness, this shouldn't be a huge problem, except that when i go to remove one of the empty guids from the set, within framework code it gets stuck in an infinite loop.  I have not Reflected this to see where, but i would guess that it is not pleased having duplicate keys internally.  Interestingly enough, if i replace the hashset with a List<Guid>, all is well.

So here's the kicker.  This is not reproducible on my development box, only on this QA server.  The possible reasons are many.  For instance, my dev box runs .Net 3.5 SP1, while the server is running without SP1.  My dev box is running Vista x64 hosting under cassini, while the server is running Server 2008 x64 hosting under IIS 7.  My guess for the culprit would be the former.  I am upgrading the server to SP1 today to see if that resolves the issue. 

I will update this post with the results.

Published Wednesday, March 25, 2009 9:15 AM by Brian Rudolph