Yesterday we ran into some issue where exceptions would disappear into a black hole. We had some code running within the Elapsed event of a System.Timers.Timer which seemed to crash without us being able to catch the exception in our global “unhandled exception” exception handler. It looked like we had a Ninja in our code somewhere, deadly and accurate.

So we finally figured out what was happening and I’ll explain it to you here.

To start with the code to reproduce this looks like this: An example project can be downloaded here: SilentKiller.zip

The problem here is that you’d expect the OnUnhandledException method to fire, but this doesn’t happen. It seems like the exception is silenced within the timer! It took us quite a while to find that out. But actually the MSDN documentation is accurate about this, and my colleague Paul was the first to catch this line:

In the .NET Framework version 2.0 and earlier, the Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.

So it’s not a bug, it’s a feature!

And when you peek inside the System.dll assembly from the .Net framework you’ll see the following code for the handling of the Elapsed event