Friday, February 18, 2011

Debugging Custom SharePoint Timer Jobs


SharePoint timer jobs are tasks executed on a scheduled basis by the Windows SharePoint Services timer service (owstimer.exe). They are analogous to scheduled tasks, and you can create them in any version of Windows, but SharePoint timer jobs come with many more benefits. SharePoint relies on timer jobs for a number of its functionality areas, and you can even broaden those functionalities and create your custom timer job to introduce new features.

For instance, last month I developed a custom timer job that runs on a daily basis to query all the SharePoint lists and libraries in all the site collections and insert corresponding records into a custom database table for reporting purposes.

Unfortunately, SharePoint timer jobs are tricky when it comes to debugging; it is not about attaching a debugger to w3wp.exe like what we did earlier in this issue. Troubleshooting my custom timer jobs has caused me a lot of headache; that is why I am determined to share with you all the tricks that I have learned in the course of developing a reporting timer job.

To debug custom timer jobs, follow these steps:
  1. Insert an always-failing assertion statement at the beginning of the Execute method. You should use Debug.Assert(false) rather than Trace.Assert(false) since debug calls are detached from the release builds; then you don’t have to remove them from your code before moving to staging or production.

  2. Every time the timer job starts, you will get a pop-up window like the one shown in Figure  This window   hinders the execution of the timer job until you close the message box. Note that timer jobs run in parallel, so this window will never halt the execution of other timer jobs running simultaneously. For now, leave this window alone.

3.Select Debug > Attach to Process, and attach a debugger to the Windows SharePoint timer service (owstimer.exe). Make sure that the “Show process from all users” checkbox is selected if owstimer.exe is not listed.

4.Click the Ignore button in the assertion window.

There you go!

You might be wondering why you should insert the assert statement at the beginning of the Execute method of the timer job. It is true that you can just attach a debugger to owstimer.exe and wait for the subsequent cycle of the timer job, but it could be tough to find out whether the application has been effectively attached to the process since the jobs may not fire for several minutes. You could be left with Visual Studio attached to the owstimer.exe process with breakpoints set and wondering whether the job is running or wondering whether the breakpoints are not being hit because of some problem with loading the symbol files.

Cached Assemblies!

Any time you update your custom timer job class and deploy the assembly to the global assembly cache, you must restart all the timer services in the farm. If you don’t restart the timer service, it will run the old copy of your timer job class. Yes, the timer service caches the assemblies. Restarting the SharePoint timer service is the only way to refresh the assembly cache and force it to use your updated assembly. You can achieve that from the command line using the following commands.
net stop sptimerv3
net start sptimerv3

Forcing the Execution of Timer Jobs

When you troubleshoot or test your custom timer job, you will probably want to instantly run the job without waiting for the job to run in schedule.
If you have observed the Timer job definitions in SharePoint central administration, you will find that it gives you the capability to disable the job definition but it doesn’t allow you to execute it.
Note: For the out of the box timer jobs, you can use the stsadm –o execadmsvcjobs command, but this will merely execute the administrative timer jobs but it will not execute the custom ones.
One way to work around this is changing the job schedule, deactivating and activating the feature that installs the timer jobs; this will do the trick by altering the Schedule Property of the job. You can use SharePoint Manager 2007 for monitoring the timer jobs status, schedule and the last run time. It’s very useful and time-saving rather than writing custom code to retrieve those values.

So a solution to force custom timer jobs to execute is using SharePoint object model as follows. Below is a code snippet that does the trick:

Note: Forcing a timer job to execute out of schedule will neither alter the LastRunTime property of the job nor modify the schedule, so don’t let that fool you.

Another way to force the custom timer jobs to run is using ZSTimerJob tool available at CodePlex. The tool is really nifty! It gives the administrators the ability to delete, disable and immediately run timer jobs from the browser without writing a single line of code. MARVELLOUS.

No comments:

Post a Comment