I have to run a automated job every 5 hours.
I found this post on how to create scheduled tasks, using IScheduledTaskHandler and IScheduledTaskManager.
Scheduled tasks using Orchard CMS
I copied the same code, I added my service call inside the Process function. It compiles fine. But I am not sure if I have to ‘start’ this scheduled task, like a windows service start. Does it get picked up automatically after I build the solution? When does the clock starts ticking if I want to run this job in 5 hours? And if I want to stop/pause, how can I do that?
Thanks.
EDIT:
I am getting an exception if I try to enable the custom module with task handler.
Exception Details: System.ArgumentNullException: Value cannot be null. Parameter name: source
Line 241: var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name);
Source File: orchard-1.4srcOrchardEnvironmentDefaultOrchardHost.cs Line: 241
The _shellContexts is coming up as null. If I remove the task handler class from the project/module, everything works fine.
Here is the task handler code.
public class ScheduledTaskHandler : IScheduledTaskHandler
{
private const string TaskType = "MyTaskUniqueID";
private readonly IScheduledTaskManager _taskManager;
private readonly IMyService _myService;
public ILogger Logger { get; set; }
public ScheduledTaskHandler(IScheduledTaskManager taskManager, IMyService myService)
{
_myService = myService;
_taskManager = taskManager;
Logger = NullLogger.Instance;
try
{
DateTime firstDate = new DateTime().AddMinutes(5);
ScheduleNextTask(firstDate);
}
catch (Exception e)
{
this.Logger.Error(e, e.Message);
}
}
public void Process(ScheduledTaskContext context)
{
if (context.Task.TaskType == TaskType)
{
try
{
_myService.RunJob();
}
catch (Exception e)
{
this.Logger.Error(e, e.Message);
}
finally
{
DateTime nextTaskDate = new DateTime().AddHours(5);
ScheduleNextTask(nextTaskDate);
}
}
}
private void ScheduleNextTask(DateTime date)
{
if (date > DateTime.UtcNow)
{
var tasks = this._taskManager.GetTasks(TaskType);
if (tasks == null || tasks.Count() == 0)
this._taskManager.CreateTask(TaskType, date, null);
}
}
}
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Clock starts ticking automatically when you start the app – you cannot stop/pause it.
Scheduler runs in 1 minute intervals – it checks if there are tasks that should be ran now and runs them. Tasks are being stored in database – corresponding record is always deleted just before task execution is about to start (to ensure that a given task will run only once).
If you need a recurrent job to be ran, you need to create a new task just after the previous one has finished (like in the example you linked to).
Method 2
if somebody is interested I’ve simply removed the starter code from ScheduledTaskHandler.
The following I put on some controller constructor
private void ScheduleStartTask() {
var tasks = _scheduledTaskManager.GetTasks(TaskType);
if (tasks == null || tasks.Count() == 0) {
var date = _clock.UtcNow.AddSeconds(5);
_scheduledTaskManager.CreateTask(TaskType, date, null);
}
}
and on the handler
public void Process(ScheduledTaskContext context) {
if (context.Task.TaskType == TaskType) {
try {
var x = "kuku";
} catch (Exception e) {
this.Logger.Error(e, e.Message);
} finally {
this.ScheduleNextTask();
}
}
}
private void ScheduleNextTask() {
var date = _clock.UtcNow.AddSeconds(5);
_taskManager.DeleteTasks(null, a => a.TaskType == TaskType);
_taskManager.CreateTask(TaskType, date, null);
}
Method 3
Use ILoggerFactory Instead of ILogger and then Get Logger Instance from it.
public ScheduledTaskHandler(IScheduledTaskManager taskManager,ILoggerFactory LoggerFactory, IMyService myService)
{
_myService = myService;
_taskManager = taskManager;
Logger = NLoggerFactory.CreateLogger(typeof(ScheduledTaskHandler));;
try
{
DateTime firstDate = new DateTime().AddMinutes(5);
ScheduleNextTask(firstDate);
}
catch (Exception e)
{
this.Logger.Error(e, e.Message);
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0