-1

How to create a function to auto close the programe at 06:00 am no matter does it finished its job or not?

 static void Main(string[] args)
 {
    //How to create a function to check the time and kill the programe
    foreach(var job in toDayjobs)
    {          
        runJob();
    }
 }
king yau
  • 500
  • 1
  • 9
  • 28

2 Answers2

2

This code snippet should work. Don't forget to add using System.Threading;

static void Main(string[] args)
    {
        CloseAt(new TimeSpan(6, 0, 0)); //6 AM

        //Your foreach code here

        Console.WriteLine("Waiting");
        Console.ReadLine();
    }

    public static void CloseAt(TimeSpan activationTime)
    {
        Thread stopThread = new Thread(delegate ()
        {
            TimeSpan day = new TimeSpan(24, 00, 00);    // 24 hours in a day.
            TimeSpan now = TimeSpan.Parse(DateTime.Now.ToString("HH:mm"));     // The current time in 24 hour format
            TimeSpan timeLeftUntilFirstRun = ((day - now) + activationTime);
            if (timeLeftUntilFirstRun.TotalHours > 24)
                timeLeftUntilFirstRun -= new TimeSpan(24, 0, 0);
            Thread.Sleep((int)timeLeftUntilFirstRun.TotalMilliseconds);
            Environment.Exit(0);
        })
        { IsBackground = true };
        stopThread.Start();
    }
Pepernoot
  • 3,409
  • 3
  • 21
  • 46
1

This is the code to do that assuming you want to shut down the app @6:00 PM

private static bool isCompleted = false;
static void Main(string[] args)
        {
        var hour = 16;
        var date = DateTime.Now;

        if (DateTime.Now.Hour > hour)
            date = DateTime.Now.AddDays(1);

        var day = date.Day;

        var timeToShutdown = new DateTime(date.Year, date.Month, day, 18, 0, 0).Subtract(DateTime.Now);

        var timer = new System.Timers.Timer();
        timer.Elapsed += Timer_Elapsed;
        timer.Interval = timeToShutdown.TotalMilliseconds;
        timer.Start();

 //Do the forloop here
 isCompleted= true;

            Console.WriteLine("Press any key to continue");
            Console.Read();
        }

        private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var timer = (sender as System.Timers.Timer);
            timer.Stop();
            timer.Dispose();

            if(isCompleted == false)
              throw new Exception("Work was not completed");
            Environment.Exit(0);
        }
Haitham Shaddad
  • 4,336
  • 2
  • 14
  • 19
  • May I suggest a different calculation for the end time, ending at 6:00 AM? `var endTime = DateTime.Now.Hour < 6 ? DateTime.Today.AddHours(6) : DateTime.Today.AddDays(1).AddHours(6);` This handles both, cases where current time is before 6:00 and current time is after 6:00 - end on the next day. – grek40 Sep 28 '16 at 10:37
  • @grek40 if now is 2:00 AM, then your code will result in 8:00 AM not 6:00 AM, if the time was 8:00 AM, then it will be second day at 2:00 PM which is wrong in both cases – Haitham Shaddad Sep 28 '16 at 10:41
  • @HaithamShaddad so how to modify the code to fit both case? – king yau Sep 28 '16 at 10:42
  • @HaithamShaddad beware of the difference between `DateTime.Now` and `DateTime.Today`. – grek40 Sep 28 '16 at 10:45
  • @grek40 Thanks, I didn't notice it, your solution is neat – Haitham Shaddad Sep 28 '16 at 10:48
  • @HaithamShaddad where should i place the foreach code? above the Console.WriteLine("Press any key to continue");? – king yau Sep 28 '16 at 10:48
  • @kingyau put it after the timer starts, because if you put it before, your timer won't have a chance to start – Haitham Shaddad Sep 28 '16 at 10:50
  • I think you current solution would break down on the last day of the month with `day = DateTime.Now.AddDays(1).Day` being `1` but your month/year is not increased. – grek40 Sep 28 '16 at 11:24
  • @grek40 Yes, you are correct, I have updated the code to use a date object after increment its days by 1, this way if it was the last day in month and we added one more day, the month will be increased as well, the same for if it was the last day in year – Haitham Shaddad Sep 28 '16 at 11:28
  • If i want to throw an exception if the program is closed when the program is still running, how/ where to place the exception throwing code? – king yau Sep 28 '16 at 13:14
  • You can have a variable named `isCompleted` of type Boolean, initialize it before you start the foreach to false and set it to true when you are done from the foreach, in the `Timer_Elapsed` method check if the `isCompleted` is false then throw an exception – Haitham Shaddad Sep 28 '16 at 13:17
  • So i should write the code to handle the job that before the programme being killed under timer.Dispose();, right? – king yau Sep 28 '16 at 13:21
  • I have updated the answer with the `isCompleted` flag – Haitham Shaddad Sep 28 '16 at 13:28
  • @kingyau This whole throwing-around-exceptions idea looks somewhat suspicious. If your jobs finished, your program would just exit, wouldn't it? So if the timer reaches its event, you already know that the work is not completed and if you throw there, you will not reach the exit code. I didn't research the exception influence on running jobs, but you are better of writing some handler code at this place instead of throwing. – grek40 Sep 28 '16 at 13:49