SharePoint: Successfully Debugging Custom Timer Jobs

Timer Job
You can even write a timer job to send you an email when your eggs are done.

I’ve developed and debugged my share of custom SharePoint Timer Jobs in my day, yet there is still a rather tricky ‘gotcha’ that seems to trip me up every time, even though I am well aware of it. Perhaps writing this article about it will help me remember next time?

My debugging style tends to be something like this: Change a line of code, run the change in debug mode. Change a line of code, run it in debug mode. You get the picture. While not always the most efficient way, it’s a fairly reasonable way to get the job done. Once my change allows the debugger to get past the error that was being thrown, I know I can move on to the next part of the logic.

However, when you’re dealing with SharePoint, no process is this simple. SharePoint likes to cache lots of stuff, sometimes causing it to behave in a somewhat unexpected manner. The same goes for DLLs. In order to increase system performance, SharePoint’s timer service caches all of the assemblies it needs to run all defined timer jobs, including any custom-developed jobs.

Services
The Services window on Windows Server 2008 R2 Standard

So, what does this mean?

Even if you change your code and redeploy the solution to SharePoint, the Timer Job will execute using the old, cached DLL, rather than the new DLL from the GAC. The Visual Studio debugger will be unaware that it is not using the new DLL, and can lead to some interesting results. If the debugger seems to be acting like a drunken mental patient, this is huge clue that SharePoint is running the old DLL.

Remember this:

EVERY time you make a single change to your timer job and wish to debug, you must restart the Windows SharePoint Services Timer service in SharePoint 2007, and the SharePoint 2010 Timer service in SharePoint 2010. This can be done by navigating to Start > Administrative Tools > Services, right-clicking on the service, and selecting Restart. The next time the job runs, it will use the new version of the DLL that you deployed.

To avoid this problem, only one additional step is necessary in my debugging process. It’s simple and easy, but it manages to get me every time.

  • http://twitter.com/sombaki Bryant Sombke

    Note: You can also make sure to increment the version number of your DLL each time you make a change. If the version number is different, the Timer Service won’t be able to use a cached version. Either way, it should have the same effect.

  • R Ellerweg

    Hi Bryan,

    just stumbled upon your article. Everytime I work with timer jobs in Sharepoint I add a “net stop SP4Timer; net start SP4Timer” to my pre build events in visual studio. That way I don’t need to care about the timer job.

    Regards

    Roland

    • http://twitter.com/sombaki Bryant Sombke

      That’s a great tip! It won’t work on a production environment, but it will work wonderfully in a DEV environment. Thanks!

  • http://twitter.com/sombaki Bryant Sombke

    That’s a great tip! It won’t work on a production environment, but it will work wonderfully in a DEV environment. Thanks!

  • Barış Engez

    I was debugging my execute code and it was freaking me out. i declared an x and did a x++ but it was even throwing exception on that, completely mind blowing! I read your sentence : ”
    If the debugger seems to be acting like a drunken mental patient, this is huge clue that SharePoint is running the old DLL.” – I say HELL YEAH! thank you