如何确保计划任务仅运行一次Orchard CMS

时间:2013-11-22 10:23:40

标签: scheduled-tasks orchardcms

我需要在Orchard CMS中创建一次性计划任务,该任务在发布自定义内容类型时启动。

我有一个scheduledTask处理程序:

public class MyCustomTaskHandler : IScheduledTaskHandler
{
    private const string TaskType = "MyCustomTask";
    private readonly IMyCustomService _customService;
    private readonly IScheduledTaskManager _taskManager;

    public ILogger Logger { get; set; }

    public MyCustomTaskHandler(IMyCustomService customService, IScheduledTaskManager taskManager)
    {
        _customService = customService;
        _taskManager = taskManager;
        Logger = NullLogger.Instance;

    }

    public void Process(ScheduledTaskContext context)
    {
        if (context.Task.TaskType == TaskType)
        {
            try
            {
                Logger.Information("Proceesing scheduled task of content item #{0}", context.Task.ContentItem.Id);

                _customService.Execute(context.Task.ContentItem);
                _taskManager.DeleteTasks(null, a => a.TaskType == TaskType);
            }
            catch (Exception e)
            {
                this.Logger.Error(e, e.Message);
            }
        }
    }

在我的内容项发布后,我使用此代码创建计划任务。

_contentManager.Publish(item);

//set off background task
_scheduledTaskManager.CreateTask("MyCustomTask", DateTime.UtcNow, item);

然而,每次它每分钟运行两次(两次)。我只希望它运行一次然后删除。我错过了什么? ScheduledTaskHandler是否实现了错误的接口?

注意 - 我已经阅读了How to run scheduled tasks in OrchardScheduled Tasks using Orchard CMS,但似乎都没有包含答案/我遇到了问题

更新:我也一直在研究IBackgroundTask而不是IScheduledTask(Handler)但是我不知道如何“触发”事件而不是它只是在后台持续运行,所以我又回到了不知道如何运行一次性/单一任务。

(我将考虑在内容类型上设置一个标志,说它已准备好打包,然后一旦触发就将标志设置为“off”以尝试确保它只运行一次 - 但是这对我来说感觉像是一个超级大胆的工作:/

1 个答案:

答案 0 :(得分:1)

是的,我不认为计划的任务是你需要的。如果我理解正确,您只想在发布内容类型时运行任务。所以我认为实现这一目标的正确方法是挂钩ContentHandler中的OnPublished事件。发布零件时会触发此操作。

这是我在记事本中写的一些伪esque代码......

namespace MyModule
{
    [UsedImplicitly]
    public class MyPartHandler : ContentHandler
    {
        private readonly ICustomService customService;

        public MyPartHandler(IRepository<MyPartRecord> repository, ICustomService customService)
        {
            Filters.Add(StorageFilter.For(repository));
            this.customService = customService;

            OnPublished<MyPart>((context, part) => {
                if(part.ContentItem.ContentType != "MyContentType")
                    return;

                customService.Exeggcute(part);
            });
        }
    }
}