我需要在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 Orchard和Scheduled Tasks using Orchard CMS,但似乎都没有包含答案/我遇到了问题
更新:我也一直在研究IBackgroundTask而不是IScheduledTask(Handler)但是我不知道如何“触发”事件而不是它只是在后台持续运行,所以我又回到了不知道如何运行一次性/单一任务。
(我将考虑在内容类型上设置一个标志,说它已准备好打包,然后一旦触发就将标志设置为“off”以尝试确保它只运行一次 - 但是这对我来说感觉像是一个超级大胆的工作:/
答案 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);
});
}
}
}