-3

i am trying to achieve two different methods to start execution at the same time with different time intervals. method1() to be executed every 5 minutes and method2() to be executed every 10 minutes. i am using console application to achieve this.

    public static Int64 counter = 0;
    static void Main(string[] args)
    {            
        bool tryAgain = true;
        while (tryAgain)
        {
            try
            {
                Thread thread1 = new Thread(new ThreadStart(TimerMethod1));
                Thread thread2 = new Thread(new ThreadStart(TimerMethod2));

                thread1.Start();
                thread2.Start();
            }
            catch(Exception ex)                
            {
                Thread thread1 = new Thread(new ThreadStart(TimerMethod1));
                Thread thread2 = new Thread(new ThreadStart(TimerMethod2));

                thread1.Start();
                thread2.Start();

                Console.WriteLine("Error ==>" + ex.ToString());
            }
        }
    }     
    public static void method1(object sender, System.Timers.ElapsedEventArgs e)
    {           
        Console.WriteLine("method1 --" + System.DateTime.Now.ToString() + "=====>" + counter.ToString());
        counter++;
    }
    public static void method2(object sender, ElapsedEventArgs e)
    {            
        Console.WriteLine("method2 --" + System.DateTime.Now.ToString());           
    }

    public static void TimerMethod1()
    {
        System.Timers.Timer t = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds); //execute every 5 minutes
        t.AutoReset = true;
        t.Elapsed += new System.Timers.ElapsedEventHandler(method1);
        t.Start();
    }
    public static void TimerMethod2()
    {
        System.Timers.Timer t = new System.Timers.Timer(TimeSpan.FromMinutes(10).TotalMilliseconds); //execute every 10 minutes
        t.AutoReset = true;
        t.Elapsed += new System.Timers.ElapsedEventHandler(method2);
        t.Start();
    } 

i am using two different timers to manage each method. this puts execution into loop without following timer. counter is just to check number of occurrence for particular method.

note: i just want to start execution of both methods at same time. both should work independently and not depend on each other once started.

Hardik Mer
  • 824
  • 4
  • 14
  • 26
  • 2
    Why do you need a separate threads? Using a two timers will be enough – Pavel Anikhouski May 30 '20 at 18:00
  • How precise do the intervals need to be? Do they need to start executing at precisely those intervals? Or, after a method excutes once, can you just wait five or ten minutes and execute it again? – Scott Hannen May 30 '20 at 18:00
  • @MerHardik, PavelAnikhouski is right also if you wanted to continue with a two timer approach. They do not need to be initialized on dedicated threads since the elapsed events will be call on separate threads anyway. Set them up on your main thread with the `Elapsed` delegates and start them of running. – George Kerwood May 30 '20 at 18:06
  • i want both method1 and method2 to be started at the same time... method1 will be executed every 5 minutes. and method2 should be executed after every 10 minutes without waiting for each other to be completed – Hardik Mer May 30 '20 at 18:07
  • Yes, we understand. To achieve that, you do not need to create the two timers on separate `Threads`. Every time an `Elapsed` event occurs, it will invoke the delegated method on a new `Thread`, they will not block one another. – George Kerwood May 30 '20 at 18:15

1 Answers1

2

Unless I've misunderstood the requirement for dedicated threads, you can do this using Task to allow for asynchronous operation. A single timer can be used with the Elapsed event dispatching tasks allocated to run your methods. A simple bool can be "toggled" to determine if Method2() is called or not on each five minute iteration.

class Program
{
    static bool runMethod2;

    static void Main(string[] args)
    {
        runMethod2 = true;
        Timer masterTimer = new Timer()
        {
            // Interval of 5 minutes in ms
            Interval = 5 * 60 * 1000
        };
        masterTimer.Elapsed += EventManager;
        masterTimer.Start();

        while (true) { }

    }

    private static void EventManager(object sender, ElapsedEventArgs e)
    {
        runMethod2 = !runMethod2;
        Task.Run(() => Method1());
        if (runMethod2) Task.Run(() => Method2());
    }

    static void Method1()
    {

    }

    static void Method2()
    {

    }
}
George Kerwood
  • 1,248
  • 8
  • 19
  • what if method1 takes more than 5 minutes to execute will it execute method1 again without waiting for previous method1 execution to be completed on next interval? – Hardik Mer May 30 '20 at 18:16
  • 1
    Yes, there is no `CallBack` or blocking here. If `Method1()` is called at minute 5, even if it takes >5 minutes to run, it will be called again at minute 10. If that is expected to happen, be aware that if `Method1()` references some external resource, that, that resource is capable of supporting access from multiple threads since 2 different "instances" of `Method1()` will be trying to access it at the same time from separate threads. – George Kerwood May 30 '20 at 18:20
  • I guess this is better idea to use single timer. what if we consider method1 to be executed every 5 minutes and method2 to be executed every 7 minutes? – Hardik Mer May 30 '20 at 18:25
  • 1
    @MerHardik In that case, with your methods "out of phase", then you would be better with dedicated timers. – George Kerwood May 30 '20 at 18:44
  • @MerHardik Or you could set a single timer to an `Elapsed` of 1 minute and on each event increment a `int minuteCounter`. To then determine in logic which events to run, you could do `if (minuteCount % 5 = 0) Method1()` and `if (minuteCount % 7 = 0) Method2()`. Here you are using modulus to determine if the current minute is a multiple of your frequency. If it is, producing no remainder, you can execute. – George Kerwood May 31 '20 at 05:24