Reputation: 529
I need to create a one-off scheduled task in Orchard CMS, which is kicked off when a custom content type is published.
I have a scheduledTask handler:
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);
}
}
}
And after my content item is published I use this code to create the scheduled task.
_contentManager.Publish(item);
//set off background task
_scheduledTaskManager.CreateTask("MyCustomTask", DateTime.UtcNow, item);
However it runs twice each time and it continues to run (twice) every minute. I only want it to run once and then delete. What am I missing? Is ScheduledTaskHandler the wrong interface to implement?
Note - I've already read through How to run scheduled tasks in Orchard and Scheduled Tasks using Orchard CMS but neither seem to contain the answer / have the problem I'm getting
UPDATE: I've also been looking into IBackgroundTask rather than IScheduledTask(Handler) but I can't tell how to "fire" the event rather than it just running continually in the background, so I'm back to not knowing how to run a one off / singular task.
(I'm going to look into setting a flag on the content type to say it's ready to be packaged, and then setting the flag to "off" once it's fired to try and make sure it only runs once - but this feels like a super-bodge-job to me :/
Upvotes: 0
Views: 1080
Reputation: 6591
Yeah I don't think a scheduled task is what you need. If I understand you correctly, you just want to run a task when a content type is published. So what I think would be the correct way to achieve this would to hook into the OnPublished event in a ContentHandler. This is triggered when a part is published.
Here is a bit of pseudo-esque code I wrote in notepad...
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);
});
}
}
}
Upvotes: 1