0

I have made a C# alarm clock and it's working fine. the problem is that when it runs it consumes 20% of the processor (on an i5 2410M processor) what should I do? here is my code:

using System;
namespace assigment1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime uptime = new DateTime (2013,12,10,4,0,0);
            Console.WriteLine("This alarm is set to go off at 4:00 am");
            while (true)
            {

                if (DateTime.Now.Minute == uptime.Minute && DateTime.Now.Hour == uptime.Hour)
                {
                    for (int j = 1000; j < 22767; j++)
                     {


                        Console.Beep(j, 500);
                        Console.Write("Wake up! it is {0}:{1} already! ", DateTime.Now.Hour, DateTime.Now.Minute);
                     }

                }
             }
        }
    }
}
Med Zamrik
  • 303
  • 2
  • 5
  • 14
  • Actually without any delay (and be it only half a second) you can be glad it's only taking up 20% :-) – Thorsten Dittmar Dec 10 '13 at 12:36
  • You're asking the wrong question. You should be asking why it's taking almost all the CPU for one of the cores. Rather than fixing the problem, know what the cause is. – Skizz Dec 10 '13 at 12:39
  • Plus, It's Assignment*. See http://stackoverflow.com/questions/8934570/c-sharp-namespaces-and-assemblies-best-practice – Philip Gullick Dec 10 '13 at 12:46

6 Answers6

2

This is because your while loop is running continuously without any break. Add a Thread.Sleep. This will add a pause in between checks and greatly increase your performance:

class Program
{
    static void Main(string[] args)
    {
        DateTime uptime = new DateTime (2013,12,10,4,0,0);
        Console.WriteLine("This alarm is set to go off at 4:00 am");
        while (true)
        {

            if (DateTime.Now.Minute == uptime.Minute && DateTime.Now.Hour == uptime.Hour)
            {
                for (int j = 1000; j < 22767; j++)
                 {


                    Console.Beep(j, 500);
                    Console.Write("Wake up! it is {0}:{1} already! ", DateTime.Now.Hour, DateTime.Now.Minute);
                 }                     

            }

            Thread.Sleep(1500); // Sleep 1.5 seconds.
         }
    }
}
gleng
  • 6,185
  • 4
  • 21
  • 35
1

if you want an alarm clock why you don't use Timer Class

BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
  • the timer would make it go off after a time limit (like after 5 hours) but I want to it to keep running all the time and go off when it's the right time. – Med Zamrik Dec 10 '13 at 13:10
  • that's not true it depends which type of timer you will use this link discuss all types of timers offered by the .net http://msdn.microsoft.com/en-us/magazine/cc164015.aspx – BRAHIM Kamel Dec 10 '13 at 13:46
1

I don't know if you can do that, but you can change the thread priority of the executing thread via the Priority property. You may want to try the following:

Thread.CurrentThread.Priority = ThreadPriority.Lowest;

Also, I don't think you really want to cap it. If the machine is otherwise idle, you'd like it to get busy on with the task, right? ThreadPriority helps communicate this to the scheduler.

ValarmorghulisHQ
  • 989
  • 1
  • 11
  • 31
1

You are putting the check within a while loop, which means it will be utilising a large proportion of your processor time.

I would suggest having a look at this article (http://www.infolet.org/2012/11/create-digital-clock-on-c-sharp-program-code.html) which describes how to do this using the Timer Class.

UPDATE: This SO answer is pretty nice and may be more suited if you're happy to use events; https://stackoverflow.com/a/1493235/465404

Community
  • 1
  • 1
Sam Jenkins
  • 1,284
  • 1
  • 12
  • 30
1

You need to calculate the time till till the alarm should beep and use the timer class. Just set the interval to the time remaining till alarm and stop the timer after that. Something like this should work

DateTime alarmTime = new DateTime(2013,12,10,4,0,0);
System.Windows.Forms.Timer alarmTimer = new System.Windows.Forms.Timer();
alarmTimer.Interval = (alarmTime - DateTime.Now).Milliseconds;
alarmTimer.Tick += alarmTimer_Tick;
alarmTimer.Start();

your event

void alarmTimer_Tick(object sender, EventArgs e)
{
    alarmTimer.Stop();
    Console.Write("Wake up! it is {0}:{1} already! ", DateTime.Now.Hour, DateTime.Now.Minute);
}
Ehsan
  • 31,833
  • 6
  • 56
  • 65
0

I think you should definitely be using a Timer class for your alarm and just change the tick interval accordingly. This will easily allow you to manage recurrence of the alarm as well.

So you're interval will be the difference in time between when the alarm is set and when you want it to go off.

I have used multiple of these running concurrently in a Win Forms app with very small resource utilisation.

rex
  • 3,133
  • 6
  • 35
  • 62