So for a long time now I have been promising an article on creating DotNetNuke Scheduled jobs and finally I'm actually getting it written. This article is actually the first in a series of two articles. This one will start out with the programming process involved, and the general "manual" setup process to actually get the job going. The second article will focus on using the DotNetNuke API's to be able to validate and configure a scheduled job from within a module, making the user setup process easier.
Overview of Scheduled Jobs
Before I get into the specific code for a DotNetNuke scheduled job I want to talk a little bit about what a job is, and how you are going to interact with it. At a foundation level a DotNetNuke Scheduled Job is simply a class that inherits from the SchedulerClient base class. As such you override a "DoWork" method that performs whatever custom action you desire.
The base class exposes a ScheduleHistoryItem class that provides a mechanism for your process to report success/failure and a method to report helpful information to users via the "History" reporting that is available within DotNetNuke.
Now, this all seems pretty simple right? Well there is one common gotcha with scheduled jobs that you want to be aware of, and that is the impacts of the "Scheduler Mode" property within Host Settings. Now the first question comes to mind is how would that change things, well the key is that if the scheduler is set to "Timer Mode", which is my recommended setting, Scheduled jobs will NOT have access to an HttpContext as they are processing. This can make file access a bit harder. In my next article I'll give more details regarding the process to handle this.
The following is a sample scheduled job class with all comments and custom code removed.
using System; using System.Collections.Generic;
public class YourJob : SchedulerClient
public YourJob (ScheduleHistoryItem oItem)
this.ScheduleHistoryItem = oItem;
public override void DoWork()
//Perform required items for logging
//Your code goes here
//To log note
this.ScheduleHistoryItem.Succeeded = true;
catch (Exception ex)
this.ScheduleHistoryItem.Succeeded = false;
InsertLogNote("Exception= " + ex.ToString());
As you can see the format is pretty basic, thee are just a few key items to remember.
- Always wrap your custom code inside of a Try/Catch block to ensure that you can handle and log the detailed information about any error that might occur
- To enable logging and to show that your job has truly started, call the Progressing method early in your code
- Use the available AddLogNote functionality to log additional information that might be helpful. (For example Records Affected, or other types of diagnostic information)
From here you can build out your scheduled job as needed.
Installing/Configuring the Job
Once you have created your Scheduled Job and installed the dll, either via a module package or some other process, you simply need to add a new item to the DotNetNuke Schedule. To complete this process you will simply go to "Host" -> "Scheduler" and select the "Add Item to Schedule" option. The following is an outline of the values that you supply.
- Full Class Name and Assembly - Your assembly and class name, in the format of FQCN, Assembly (Example YourNamespace.YourJob, YourNamespace where YourNamespace.dll was the compiled project)
- Schedule Enabled - Check this to enable the item
- Time Lapse and Retry - To configure the frequency, values you desire
- Retain History - If set to none, any log writes you do will not be preserved, if using the AddLogNote option, you will want to retain at least a few values.
All of the other items are dependent upon your environment and specific needs. Once you save the record, your job will be scheduled to execute for the first time.
DotNetNuke scheduled jobs are very simple to build and are a great method to handle batch or offline processing for many needs. With a bit of planning and logging in place you can handle complex business needs easily. Feel free to share feedback below.
This blog post is cross-posted from my personal blog.