Targeting scheduled task event in code

Kàren Vaganyan asked on March 28, 2017 22:18

Is there a global event to target the execution of scheduled system tasks? I have 2 tasks that were created as a result of a scheduled email marketing campaign, and I’d like to target them both after they get executed.

Thanks!

Recent Answers


Trevor Fayas answered on March 28, 2017 22:30

I don't see one specifically in the API for 8.2, however here are some options, however when a task is run, the CMS.ScheduledTask object is updated (the database updates the TaskLastModifiedField)

You can use the generic ObjectEvent.Update.After should do the trick, one sec and i'll get you the code, once my visual studio stops acting up.

0 votesVote for this answer Mark as a Correct answer

Kàren Vaganyan answered on March 28, 2017 22:37

Oh OK cool. I didn't think of that haha
That's OK, you don't have to, I appreciate it though. I should be able to figure it out from here.

Thanks!

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on March 28, 2017 22:37

Try this!

using CMS.Base;
using CMS.Forums;
using CMS.DataEngine;
using CMS.Helpers;
using CMS.Scheduler;
/// <summary>
/// Summary description for LoaderModule
/// </summary>
[CustomForumGroupHandlers]
public partial class CMSModuleLoader
{
    /// <summary>
    /// Custom attribute class.
    /// </summary>
    private class CustomForumGroupHandlers : CMSLoaderAttribute
    {
        /// <summary>
        /// Called automatically when the application starts
        /// </summary>
        public override void Init()
        {
            ObjectEvents.Update.After += Update_After;
        }

        void Update_After(object sender, ObjectEventArgs e)
        {
            if (e.Object.TypeInfo.ObjectType == TaskInfo.OBJECT_TYPE)
            {
                TaskInfo theTask = (TaskInfo)e.Object;
                switch (theTask.TaskName)
                {
                    case "MyTask":
                        // Do stuff
                        break;
                }
            }
        }
    }
}
0 votesVote for this answer Mark as a Correct answer

Zachary Perry answered on March 28, 2017 22:44

Might be able to use TaskInfo.TYPEINFO.Events.Update.After +=

When the task first runs it updates and sets the TaskNextRunTime to null I believe, and after it completes it sets the TaskNextRunTime again, so you might have to check that value to see if it is set, so you don't run your code twice for every one time the task runs. Something like this:

   if (task.TaskNextRunTime == TaskInfoProvider.NO_TIME)
            {
                //Before it executes
            }
            else
            {
                //after it executes
            }
1 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on March 28, 2017 23:17 (last edited on March 28, 2017 23:18)

Zach's correct...forgot about the TYPEINFO.events specific shortcut.

If it does hit more than once, use the RecrusionControl class. You call it with a key of some sorts (try to make it unique to that execution chain, like the task name+the date + hour). First time it's called, the "Continue" is true, next time it's false

if(CMS.Base.RecursionControl("SomeKey", false).Continue)

Learned that trick a while back.

1 votesVote for this answer Mark as a Correct answer

Zachary Perry answered on March 28, 2017 23:23

I like that trick, would have came in handy a bunch of times.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.