1
\$\begingroup\$

My app has several periodic tasks. So I created this very simple generic task scheduler (got sick of copy-pasting code, which is based on Timers). It is very very basic and simple, can you find anything wrong with it?

//generic scheduling-job class
public static class PeriodicTask
{
    //keep a list of scheduled actions
    static Dictionary<Action, CancellationTokenSource> _scheduledActions = new Dictionary<Action, CancellationTokenSource>();

    //schedule an action
    public static async Task Run(Action action, TimeSpan period)
    {
        if (_scheduledActions.ContainsKey(action)) return; //this action is already scheduled, get out

        var cancellationTokenSrc = new CancellationTokenSource(); //create cancellation toket so we can abort later when we want

        _scheduledActions.Add(action, cancellationTokenSrc); //save it all into our disctionary

        //main scheduling loop
        Task task = null;
        while (!cancellationTokenSrc.IsCancellationRequested)
        {
            if (task == null || task.IsCompleted) //skip if previous invocation is still running (our requirements allow that)
                task = Task.Run(action);

            await Task.Delay(period, cancellationTokenSrc.Token);
        }
    }

    public static void Stop(Action action)
    {
        if (!_scheduledActions.ContainsKey(action)) return; //this method has not been scheduled, get out
        _scheduledActions[action].Cancel(); //stop the task
        _scheduledActions.Remove(action); //remove from the collection
    }
}

Usage

PeriodicTask.Run(MyStaticMethod, TimeSpan.FromHours(1));
PeriodicTask.Stop(MyStaticMethod);

private static void MyStaticMethod()
{
    //do something
}
\$\endgroup\$
  • \$\begingroup\$ Why use "static" everywhere? \$\endgroup\$ – Aron Dec 4 '17 at 22:49
  • \$\begingroup\$ @Aron why not? I want a static "fire and forget" pattern. PeriodicTask.Run(doStuff); \$\endgroup\$ – jitbit Dec 4 '17 at 23:00
  • \$\begingroup\$ OK. I prefer to use objects so I'd be thinking new PeriodicTask(doStuff).Run(); \$\endgroup\$ – Aron Dec 6 '17 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.