by Vesselin Vassilev
Last Updated On Apr 2, 2018
It consists of five parts:
- minute
- hour
- day of month
- month
- day of week
Example:
50 11 * * * - means every day at 11:50AM
0 4 1,10 * * - means every 1st and 10th day of the month, at 4:00AM
20 4 * * SUN - means every Sunday at 4:20AM
A great tool to use for creating/testing cron expressions is https://crontab.guru
Now, let's have a look at the code.
First, we register our custom scheduled task in Global.asax.cs:
using
SitefinityWebApp.Custom.ScheduledTasks;
using
System;
using
Telerik.Sitefinity.Services;
namespace
SitefinityWebApp
{
public
class
Global : System.Web.HttpApplication
{
protected
void
Application_Start(
object
sender, EventArgs e)
{
SystemManager.ApplicationStart += SystemManager_ApplicationStart;
}
private
void
SystemManager_ApplicationStart(
object
sender, EventArgs e)
{
CustomScheduledTaskBase.RegisterCustomScheduledTasks();
}
}
}
public
static
void
RegisterCustomScheduledTasks()
{
using
(SchedulingManager manager = SchedulingManager.GetManager())
{
List<ScheduledTaskData> allTasks = manager.GetTaskData().ToList();
// get all defined custom Scheduled tasks in this assembly
var scootTasks =
typeof
(CustomScheduledTaskBase).Assembly
.GetTypes()
.Where(t => t.IsSubclassOf(
typeof
(CustomScheduledTaskBase)) && !t.IsAbstract)
.Select(t => (CustomScheduledTaskBase)Activator.CreateInstance(t));
foreach
(var task
in
scootTasks)
{
var taskData = allTasks.Where(t => t.TaskName == task.TaskName).ToList();
if
(taskData.Count == 0)
{
task.ScheduleCrontabTask();
}
else
{
foreach
(var td
in
taskData)
{
// delete failed or stopped tasks and those that have been running for
// more than 3 hours
if
(
td.Status == TaskStatus.Failed || td.Status == TaskStatus.Stopped ||
(td.IsRunning && td.LastModified.AddHours(3) < DateTime.UtcNow)
)
{
manager.DeleteTaskData(td);
manager.SaveChanges();
}
}
}
}
}
}
public
void
ScheduleCrontabTask()
{
using
(var manager = SchedulingManager.GetManager())
{
var task = (CustomScheduledTaskBase)Activator.CreateInstance(
this
.GetType());
task.Id = Guid.NewGuid();
task.ScheduleSpecType = "crontab";
task.Title = task.TaskName;
task.ScheduleSpec = CrontabExpression;
task.ExecuteTime = CrontabHelper.GetExecuteTime(CrontabExpression, scheduleSpecType);
manager.AddTask(task);
manager.SaveChanges();
}
}
using
System;
using
System.Threading;
namespace
SitefinityWebApp.Custom.ScheduledTasks
{
public
class
DemoScheduledTask : CustomScheduledTaskBase
{
public
override
string
CrontabExpression
{
get
{
// you can read the value from a custom config section
// execute the task every day at 11:50AM
return
"50 11 * * *"
;
}
}
protected
override
void
ExecuteTheTask()
{
for
(
int
i = 1; i <= 100; i++)
{
// this is useful if you are going to provide a UI that shows the current task progress
this
.UpdateProgress(i,
"Doing stuff {0}"
.Arrange(i));
// do your stuff...
Thread.Sleep(2000);
}
}
}
}
<
div
class
=
"row"
>
<
label
>
You can manually start the task by clicking the button below
</
label
>
<
div
>
<
button
class
=
"sfLinkBtn sfSave"
onclick
=
"return start();"
>Manual Start Task</
button
>
</
div
>
</
div
>
<
div
class
=
"row"
style
=
"margin-top:50px;"
>
<
div
id
=
"progressbar"
></
div
>
<
div
id
=
"status"
style
=
"margin-top:30px;"
></
div
>
</
div
>
<script>
var
$progress =
null
;
var
$status = $(
"#status"
);
var
_intervalHandle =
null
;
$(
function
() {
// .container is the wrapper class of the parent Layout widget
var
$editDiv = $(
".container"
);
if
($editDiv.parent().hasClass(
"sfHeader"
)) {
// edit div is in the wrong place for some reason in SF 10.1
// we need to move it out of sfHeader, to become a sibling instead of child
$editDiv.insertAfter(
".sfHeader"
);
}
// init kendo
$progress = $(
"#progressbar"
).kendoProgressBar({
type:
"percent"
}).data(
"kendoProgressBar"
);
// in case user refreshes the page
beginPolling();
})
function
start() {
$.ajax({
url: window.location.pathname +
"/startScheduledTask?taskName=SitefinityWebApp.Custom.ScheduledTasks.DemoScheduledTask"
,
type:
"GET"
})
.done(
function
(data) {
if
(data ==
"Success"
) {
alert(
"The task has started successfully, you can check its status below"
);
beginPolling();
}
})
.fail(
function
(jqXHR, textStatus) {
console.log(jqXHR);
alert(jqXHR.responseText);
});
return
false
;
}
function
beginPolling() {
refreshProgressBar();
_intervalHandle = window.setInterval(
function
() {
refreshProgressBar();
}, 1500);
}
function
_removeHandlers() {
if
(_intervalHandle) {
window.clearInterval(_intervalHandle);
_intervalHandle =
null
;
}
}
function
refreshProgressBar() {
// get task progress from Sitefinity Scheduling Service
$.ajax({
url:
"/Sitefinity/Services/SchedulingService.svc/taskName/SitefinityWebApp.Custom.ScheduledTasks.DemoScheduledTask/progress?providerName="
,
type:
"GET"
})
.done(
function
(data) {
$progress.value(data.ProgressStatus);
if
(data.StatusMessage)
$status.text(data.StatusMessage);
else
$status.text(
""
);
if
(data.ProgressStatus == 100 || data.Status != 1) {
_removeHandlers();
}
})
}
</script>
https://gist.github.com/VesselinVassilev/89b04f4ce7cef2610590643bafe089ca