Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeated Tasks using Timer Interval vs Task Delay

Tags:

c#

I'm implementing a scheduled job like methods and have narrowed down to approaches. One that implements a Timer Interval and the other based on Task Delay.

I've also considered using Azure Timer triggered webjobs but they do not work in a multi-instance mode. Effectively in a multi-instance application only one trigger is fired in one of the instances and the others are locked, hence increasing the instance count of my application does not increase the number of events fired.

Method A (Timer Interval)

using System;
using System.Threading.Tasks;
using System.Timers;

public class Example
{
    public static void Main()
    {
        var aTimer = new Timer();
        aTimer.Interval = 5000;
        aTimer.Elapsed += OnTimedEventA;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        var bTimer = new System.Timers.Timer();
        bTimer.Interval = 2000;
        bTimer.Elapsed += OnTimedEventB;
        bTimer.AutoReset = true;
        bTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program at any time... ");
        Console.ReadLine();
    }
    private static void OnTimedEventA(Object source, System.Timers.ElapsedEventArgs e)
    {
        Task.Run(() =>
        {
            Console.WriteLine("The Elapsed event A was raised at {0}", DateTime.Now);
        });
    }
    private static void OnTimedEventB(Object source, System.Timers.ElapsedEventArgs e)
    {
        Task.Run(() =>
        {
            Console.WriteLine("The Elapsed event B was raised at {0}", DateTime.Now);
        });
    }
}

Method B (Task Delay)

using System;
using System.Threading.Tasks;
public class Example
{
    public static void Main()
    {
        EventAAsync();
        EventBAsync();

        Console.WriteLine("Press the Enter key to exit the program at any time... ");
        Console.ReadLine();
    }
    private static async Task EventAAsync()
    {
        while (true)
        {
            Task.Run(() =>
            {
                Console.WriteLine("The Elapsed event A was raised at {0}", DateTime.Now);
            });
            await Task.Delay(TimeSpan.FromSeconds(5));
        }
    }
    private static async Task EventBAsync()
    {
        while (true)
        {
            Task.Run(() =>
            {
                Console.WriteLine("The Elapsed event B was raised at {0}", DateTime.Now);
            });
            await Task.Delay(TimeSpan.FromSeconds(2));
        }
    }
}

Both Method A and Method B, functionally do the same. They both call fire events A and B at regular intervals of 5s and 2s and forget. Now I'm trying to understand the pros and cons of both approaches. In the end, the events themselves run on separate threads. Theoretically and in practice which of the two should be adopted for handling many such event triggers to be scaled across multiple instances.

Any other methods are also welcome.

like image 777
Manikanta Dornala Avatar asked Oct 16 '17 05:10

Manikanta Dornala


People also ask

How do you run a task periodically in C#?

NET. Calling the method RT (short for Recurring Task) is pretty simple! Pass an action method that you would like to be executed in a recurring fashion, an interval in seconds and a cancellation token to cancel the task at any point later.

Does task delay block thread?

One example of a Task without side effects is Task. Delay() . You've likely used this API before; it waits asynchronously (without blocking a Thread ) for a time period to expire before continuing.

What is Task delay?

The Delay method is typically used to delay the operation of all or part of a task for a specified time interval. Most commonly, the time delay is introduced: At the beginning of the task, as the following example shows.

Is Task delay the same as thread sleep?

sleep will block a thread and task. delay will not and has a cancellation token, unless your app is pretty complex, it really doesn't matter as on the surface: task. delay and thread. sleep do pretty much the same thing.


2 Answers

Use timer instead, while both use the same clock as noted by @Evk but first approach runs timer permanently.

Using Task.Delay will be just as accurate but there is a short gap between finished Delay and starting new Delay. After long period they can become desynchronized. So distance between 5 and 2 second intervals will not be same as time where you started timing.

Using Timer that runs permanently doesn't have this problem.

like image 70
M.kazem Akhgary Avatar answered Sep 18 '22 17:09

M.kazem Akhgary


Method A is used when you have to trigger some task at regular intervals. Method B is used when you have to give regular intervals between the triggering of some task.

There is a difference if the event handler (task performed after the trigger) takes a longer time to process.

Method A : No matter how much time the task in the event handler takes, the event handler keeps getting triggered at the set time interval (code has to be reentrant).

Method B : Task completes then we sleep. So if the task takes different times to complete, the next trigger is also at different times

like image 34
Shinva Avatar answered Sep 21 '22 17:09

Shinva