How to run scheduled tasks in Orchard?

 ̄綄美尐妖づ 提交于 2019-12-18 17:23:05

问题


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.4\src\Orchard\Environment\DefaultOrchardHost.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);
        }
    }


}

回答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).




回答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);
    }



回答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);
        }
    }


来源:https://stackoverflow.com/questions/11475187/how-to-run-scheduled-tasks-in-orchard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!