Scheduled tasks – tips

Here are a few tips about scheduled tasks that may spare you some debugging and angry moments.

First of all, if you are interested in how you create a simple scheduled job, please check out Ted Nybergs post.

Several developers / Load balancing environment

If the same site is up’n’running on several computers/servers but with a shared database, the scheduled job might run at the “wrong” machine. There is a setting in web.config which controls if the scheduler should be run by this instance or not. It’s an attribute to <siteSettings> called “enableScheduler”, eg. <siteSettings enableScheduler=”false” …. /> if you don’t want the scheduler to run in this instance/machine.

Another way, not to tell if the job should be executed or not, but if you want to know which computer that executed the job, is to return the computer name with the return message. This can save you a lot of frustration when are about to pull you hair of cause the changes you make in to code doesn’t affect to job. 🙂

return "[Computer: " + System.Environment.MachineName + "] " + returnMessage;

Object reference not set to an instance…
Sometimes when you work with scheduled jobs, you can get this error, even though the only thing your job does is to return a “hellow world”. I’ve experienced this a few times, but never put much effort in to find out what causes this.
However, you can easily go around this by deleteing your job and create a new one with a slightly different class name.

Impersonate
In some cases you might need to run to job as a certain user.
Specially when you want to use FindPagesWithCriteria in EPiServer CMS 5 R2. It ignores the AccessControlList and only fetches pages that the current user has access rights to read. In R2 SP1 there is a new method called FindAllPagesWithCriteria which is supposed to find all pages despite access rights.
Well, this is how you login:

[ScheduledPlugIn(Description = "Test job with impersonated user", DisplayName = "Test job")]
public class TestJob
{

public static string Execute()
{
string returnMessage;

if (EnterImpersonatedState("erik.nordin", "password"))
{
returnMessage = "Job executed with user " + PrincipalInfo.CurrentPrincipal.Identity.Name;
LeaveImpersonatedState();
}
else
{
returnMessage = "Failed to login";
}
return "[Computer: " + System.Environment.MachineName + "] " + returnMessage;
}

private static IPrincipal prevPrincipal;
private static bool EnterImpersonatedState(string userName, string password)
{
IPrincipal impersonatedUser = null;

// If you don't want to validate the user, you can use skip the if-statement:
if (Membership.ValidateUser(userName, password))
{
impersonatedUser = PrincipalInfo.CreatePrincipal(userName);
}

if (impersonatedUser == null)
{
return false;
}

prevPrincipal = PrincipalInfo.CurrentPrincipal;
PrincipalInfo.CurrentPrincipal = impersonatedUser;

return true;
}

private static void LeaveImpersonatedState()
{
PrincipalInfo.CurrentPrincipal = prevPrincipal;
}
}

13 thoughts on “Scheduled tasks – tips

  1. steven

    Could I add a custom property to my custom scheduled job? I’d like a to add a drop down for export types for instance..

  2. Erik Nordin Post author

    No, I guess you have to store that somewhere else.
    Global settings is usually stored in the start or root-page which you can access via PageReference.StartPage

  3. Pingback: EPiServer Developer Resources | Frederik Vig - ASP.NET developer

  4. Kishore

    Can you please provide some more information on “Object reference not set to an instance of an object”. My Scheduled Job started and just put this message and returned status as failed.
    When I run the Job Manually , the Job is running without any problems ,
    but, When I scheduled it the Job is faled wit message : ” Object reference not set to an instance of an object”.
    Please tell me what is really making the Scheduled Job to fail.
    Thanks alot.

  5. Krzychum

    Regarding Kishore’s question about NullPointerException: Check if you access the HttpContext.Current. It exists when you call a job manually, and is null if it runs as scheduled. It is the 99% cause of “Object reference not set to an instance of an object” when you run it as scheduled.
    To use e.g. MapPath, use HostingEnvironment.MapPath.

Comments are closed.