Me: I live in Silicon Valley with my wife, child and cat. I have worked at Microsoft since I graduated from College, both in the Macintosh Business Unit on products such as Outlook Express, Entourage, IE, and Virtual PC and in Windows Live on Hotmail, Calendar and People. I am currently a Principal Lead Program Manager on the Windows Live Social Networking team. I basically manage a team of Program Managers responsible for delivering features to support our web and client applications. I've been blogging since 2001 and like to play around with .NET in my spare time working on projects such as dasBlog (the blog that powers this site) and Send to SmugMug (an application for uploading photos to SmugMug). I blog about a number of technology and productivity related topics.
Powered by: newtelligence dasBlog 2.3.9074.18820
Disclaimer The posts on this weblog are provided "AS IS" with no warranties, and confer no rights. The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2010, Omar Shahine
E-mail
Part 2 of 2
Bug 2: TrackingHandler Thread Dies
Another problem that Scott Hanselman informed me of was that he would frequently stop receiving Trackbacks, Pingbacks and Referrals on his posts. Furthermore, it was intermittent. This was troubling since losing a Trackback means it's lost forever. Well we went hunting in the code, and thanks to some UnitTest of a theory I had found the answer.
Basically the situation is this. Scott gets a lot of traffic. More than I do. There is a thread in dasBlog that sits around waiting for Trackbacks and the like. You use it by calling trackingQueue.Enqueue(tracking) and then trackingQueueEvent.Set(). So basically dasBlog can sit there and queue a bunch of trackings, and when it's ready the thread runs to execute them. The code looks like this:
private void TrackingHandler( ){ while ( true ) { Tracking tracking; trackingQueueEvent.WaitOne(); while ( true ) { lock( trackingQueue.SyncRoot ) { tracking = trackingQueue.Dequeue() as Tracking; } if ( tracking != null ) { try { InternalAddTracking( tracking ); } catch (Exception e) { ErrorTrace.Trace(TraceLevel.Error,e); } } if ( trackingQueue.Count == 0 ) { break; } } }}
The objects below are created like so:
trackingQueue = new Queue();trackingQueueEvent = new AutoResetEvent(false);trackingHandlerThread = new Thread(new ThreadStart(this.TrackingHandler));trackingHandlerThread.IsBackground = true;trackingHandlerThread.Start();
So, can you figure out what is wrong? Well I created a unit test that called this 100 times. What I quickly found out was that even though the code was calling break when the trackingQueue.Count was equal to zero the trackingQueueEvent.WaitOne() call wasn't blocking the while loop from continuing. This caused trackingQueue.Dequeue() to throw an unhanded exception (which should have been in a try catch anyway).
Not knowing a whole lot about this kind of threading I looked at a couple of docs and found the answer. Before calling break I added trackingQueueEvent.Reset(). Problem fixed (I hope).