1

first sorry for my bad English

i want to make an order in my program when it come 12:00 AM in my PC i try with this code

    string Time = "00:00 AM";
    while (true)
    {
        if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
        {
            Console.ForegroundColor = ConsoleColor.Blue;

            // Update Days -1 Where Service = 1
            sqlCon.exec("update HelperSystem set Days = Days-1 where Service=1 and Days != 0");
            Meldung("Updated HelperSystem Table Days -1");

            // Update Service = 0 Where Days = 0
            sqlCon.exec("update HelperSystem set Service = 0 where Days = 0");
            Meldung("Updated HelperSystem Table Service = 0 Where Days = 0");



            // Update Days -1 Where Service = 1
            sqlCon.exec("update AutoEvent set Days = Days-1 where Service=1 and Days != 0");
            Meldung("Updated AutoEvent Table Days -1");

            // Update Service = 0 Where Days = 0
            sqlCon.exec("update AutoEvent set Service = 0 where Days = 0");
            Meldung("Updated AutoEvent Table Service = 0 Where Days = 0");

            Console.ResetColor();
            Thread.Sleep(120000);
        }
        Thread.Sleep(1);
    }

and when i try with breakpoint return value 12:00 AM but didn't do anything

Big Bear
  • 25
  • 4
  • 3
    Unless your program is designed to always be running, I'd really recommend Windows' Scheduled Tasks. It makes a _lot_ more sense. If your application is always running, a while(true) loop isn't the best way to accomplish this when things like timers, and async exist. Also, do you intend to use UtcNow, or your local time? – ProgrammingLlama Jun 01 '17 at 04:21
  • @john it's console application and yes it's working 24/7 on VPS and i was try with Datetime.Now and don't do anything too – Big Bear Jun 01 '17 at 04:24
  • If this intended to run all the time as you say, this approach is viable, although I would advise to compare time and decide if you can sleep for longer, save some extra CPU cycles that way. Edit: after consideration, I think you are better with a solution like [Noda Time](http://nodatime.org/) - comparing string is a bad idea, even comparing DateTime ingoring the date part is better. – Theraot Jun 01 '17 at 04:28
  • In that case, the compare doesn't work because "hh" will output "04" at 4am, not "4". You want to compare to a date formatted as "h:mm tt". – ProgrammingLlama Jun 01 '17 at 04:29
  • A single "h" should work for that. But I think @Theraot meant, take a `DateTime Time` instead and compare both times – Yatin Jun 01 '17 at 04:31
  • 1
    I suggest looking at [this post](https://stackoverflow.com/questions/8815895/why-is-thread-sleep-so-harmful) and [this post](https://stackoverflow.com/questions/8496275/c-sharp-wait-for-a-while-without-blocking) and, finally, [this](https://stackoverflow.com/questions/26656236/scheduling-task-for-future-execution), just so you understand the implications of what your code is doing. – ProgrammingLlama Jun 01 '17 at 04:41
  • Also, the `sqlCon` object is forcing you to write code that will crazy-vulnerable to sql injection attacks. – Joel Coehoorn Jun 01 '17 at 04:44
  • @john thank you so much i was forget this for 04 not only 4 u can put answer down do give u right answer :) – Big Bear Jun 01 '17 at 04:46

2 Answers2

2

If you're trying to match times using a formatted string then you should ensure you're comparing against the same format. You should do something like this:

string timeFormat = "hh:mm tt";
string Time = (new DateTime(1970, 1, 1, 0, 0, 0)).ToString(timeFormat); //12:00 AM
while (true)
{
    if (Time == DateTime.UtcNow.ToString(timeFormat))
    {
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("Run.");
        Console.ResetColor();
        Thread.Sleep(120000);
    }
    Thread.Sleep(1);
}

However, this approach isn't great. You really have nothing ensuring that the process will actually execute at the right time of day to ensure equality works. In this case you'd be very unlucky as it only has to run once in the 60 seconds that the time text is correct, but there is no guarantee. You really should compare against a specific time.

This is better:

DateTime Time = DateTime.UtcNow.AddDays(1.0).Date;
while (true)
{
    if (DateTime.UtcNow > Time)
    {
        Time = DateTime.UtcNow.AddDays(1.0).Date;
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("Run.");
        Console.ResetColor();
    }
    Thread.Sleep(1);
}

There's no need for the messy Thread.Sleep(120000); in this code.

However, you still have the Thread.Sleep(1); call which is bad.

I'd suggest using a library that has been designed for this kind of thing. Try Microsoft's Reactive Framework (NuGet "System.Reactive") and then you can do this:

IDisposable subscription =
    Observable
        .Timer(DateTimeOffset.UtcNow.AddDays(1.0).Date, TimeSpan.FromDays(1.0))
        .Subscribe(x =>
        {
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("Run.");
            Console.ResetColor();
        });

When you're closing down your app just call subscription.Dispose(); and it'll cleanly stop.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

Change string Time = "4:30 AM"; to "04:30 AM"

public static void Main()
    {
        string Time = "4:30 AM";
    while (true)
    {
        Console.WriteLine("{0}",DateTime.UtcNow.ToString("hh:mm tt"));
// Prints 04:30 AM - so that is why it does not match 4:30 AM
        if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
        {
            Console.ForegroundColor = ConsoleColor.Blue;

            // Update Days -1 Where Service = 1

            Console.WriteLine("I am In");

            Console.ResetColor();

        }
       Thread.Sleep(1000);
    }
    }