0

I am trying to do an repeated method call with Timer class.

I can get it work as I want if I have ReadKey in the main. I'm wondering why is that and is there a workaround or a better way to do this.

I do want my program to exit once the scheduled work is done.

My whole test program looks like this:

using System;
using System.Threading;

namespace TestProgram
{
    public class Program
    {
        static void Main(string[] args)
        {
            int periodInSeconds = 3;
            double durationInMinutes = 0.5;

            var scheduler = new ActionScheduler(periodInSeconds, durationInMinutes, Work);
            scheduler.Run();

            Console.ReadKey();
        }

        static void Work()
        {
            Console.WriteLine(DateTime.Now + ": Doing work...");
        }

        private class ActionScheduler
        {
            private Timer Timer;
            private DateTime StopTime;
            private int PeriodInSeconds { get; set; }
            private double DurationInMinutes { get; set; }
            private Action Action { get; set; }

            public ActionScheduler(int periodInSeconds, double durationInMinutes, Action method)
            {
                PeriodInSeconds = periodInSeconds;
                DurationInMinutes = durationInMinutes;
                Action = method;
            }

            public void Run()
            {
                StopTime = DateTime.Now.AddMinutes(DurationInMinutes);
                Timer = new Timer(TimerCallback, null, 0, PeriodInSeconds * 1000);
            }

            private void TimerCallback(object state)
            {
                if (DateTime.Now >= StopTime)
                {
                    Timer.Dispose();
                }

                Action();
            }
        }

    }
}
Tsingis
  • 508
  • 3
  • 8
  • 25
  • 1
    Because ReadLine is waiting for user input – jPhizzle Jun 07 '19 at 15:39
  • 5
    You app terminates when the last of the non-background threads terminates. Timers don't keep apps alive. Your `Main()` method represents the single non-background thread here. Perhaps you might prefer an `async Task Main() {...}` ? Note: you'd still need some kind of gate so your app knows when it can exit, but... at least then it could be an `await Console.ReadLineAsync()` :) – Marc Gravell Jun 07 '19 at 15:39
  • @MarcGravell I see. I'm pretty new to this. I'll dig into that. – Tsingis Jun 07 '19 at 15:40
  • Technically the app should run and then immediately close upon completion if the readLine is not present, but because it immediately closes, it appears as though the program crashed. but with ReadLine(). the console stays open and just chills until we hit a key. Though if you just wanna hit a key to close the program, I'd recommend ReadKey() instead of ReadLine() – jPhizzle Jun 07 '19 at 15:40
  • 2
    As an aside, I would put the `Console.ReadLine()` at the end of the `Main` method rather than in the timer class. – DavidG Jun 07 '19 at 15:41
  • Possible duplicate of [Why is the console window closing immediately once displayed my output?](https://stackoverflow.com/questions/8868338/why-is-the-console-window-closing-immediately-once-displayed-my-output) – Patrick Tucci Jun 07 '19 at 16:32

0 Answers0