4

我必须每 5 小时运行一次自动化作业。

我发现这篇关于如何使用 IScheduledTaskHandler 和 IScheduledTaskManager 创建计划任务的帖子。 使用 Orchard CMS 的计划任务

我复制了相同的代码,在 Process 函数中添加了我的服务调用。它编译得很好。但我不确定我是否必须“启动”这个计划任务,比如启动 Windows 服务。构建解决方案后会自动获取它吗?如果我想在 5 小时内完成这项工作,时间什么时候开始?如果我想停止/暂停,我该怎么做?

谢谢。

编辑:

如果我尝试使用任务处理程序启用自定义模块,我会遇到异常。

异常详细信息:System.ArgumentNullException:值不能为空。参数名称:来源

Line 241: var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name);

源文件:\orchard-1.4\src\Orchard\Environment\DefaultOrchardHost.cs 行:241

_shellContexts 出现为空。如果我从项目/模块中删除任务处理程序类,一切正常。

这是任务处理程序代码。

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


}
4

3 回答 3

5

当您启动应用程序时,时钟会自动开始计时 - 您无法停止/暂停它。

调度程序以 1 分钟的间隔运行 - 它检查是否有现在应该运行的任务并运行它们。任务被存储在数据库中 - 相应的记录总是在任务执行即将开始之前被删除(以确保给定任务将只运行一次)。

如果您需要运行周期性作业,则需要在前一个任务完成后创建一个新任务(如您链接到的示例中)。

于 2012-07-13T18:18:46.347 回答
1

如果有人感兴趣,我只是从 ScheduledTaskHandler 中删除了启动代码。下面我把一些控制器构造函数

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

在处理程序上

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);
    }
于 2013-01-02T11:04:10.910 回答
0

使用 ILoggerFactory 而不是 ILogger,然后从中获取 Logger 实例。

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);
        }
    }
于 2012-07-17T14:25:52.070 回答