Waiting for a timer event in a console application?

  • Thread starter Thread starter avivgur
  • Start date Start date
A

avivgur

Hello,
I have devised a console application that uses a System.Timers.Timer
and its Elapsed event.
The problem is that I want the program to continue to run so that each
time the event is raised, the handler will be executed.
I tried using a while(timer.Enabled) {} loop but it made the process
use 90% cpu in the task manager. What is the correct way to wait for
an event and keep the program alive in a console application?
Thanks,
Aviv.
 
avivgur,

You need a way to block the current thread without performing processing
in that thread. What I would do is create an event, and wait on the handle
for that event. Then, I would have another thread wait on the notification
from the timer. When the notification comes in, then you can set the event,
and let the main thread continue processing.

Hope this helps.
 
Just insert a System.Threading.Thread.Sleep ( 1000 ) into your loop.
The integer is milliseconds so adjust the number to suit your app...

presumably timer.Enabled is changed by the event handler? Otherwise you'll
never leave the loop!
 
What I think he wants to do is just wait for a timer. How about
Thread.Sleep()?

Thomas P. Skinner [MVP]

Nicholas Paldino said:
avivgur,

You need a way to block the current thread without performing
processing in that thread. What I would do is create an event, and wait
on the handle for that event. Then, I would have another thread wait on
the notification from the timer. When the notification comes in, then you
can set the event, and let the main thread continue processing.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


avivgur said:
Hello,
I have devised a console application that uses a System.Timers.Timer
and its Elapsed event.
The problem is that I want the program to continue to run so that each
time the event is raised, the handler will be executed.
I tried using a while(timer.Enabled) {} loop but it made the process
use 90% cpu in the task manager. What is the correct way to wait for
an event and keep the program alive in a console application?
Thanks,
Aviv.
 
But wait for the timer to do what? If the thread is sleeping, then that
thread isn't going to get any notifications, and it is really just a hack to
justify polling. The thread needs to be notified when the timer is fired,
otherwise, why have a timer at all?

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Thomas P. Skinner said:
What I think he wants to do is just wait for a timer. How about
Thread.Sleep()?

Thomas P. Skinner [MVP]

Nicholas Paldino said:
avivgur,

You need a way to block the current thread without performing
processing in that thread. What I would do is create an event, and wait
on the handle for that event. Then, I would have another thread wait on
the notification from the timer. When the notification comes in, then
you can set the event, and let the main thread continue processing.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


avivgur said:
Hello,
I have devised a console application that uses a System.Timers.Timer
and its Elapsed event.
The problem is that I want the program to continue to run so that each
time the event is raised, the handler will be executed.
I tried using a while(timer.Enabled) {} loop but it made the process
use 90% cpu in the task manager. What is the correct way to wait for
an event and keep the program alive in a console application?
Thanks,
Aviv.
 
really just a hack

yep. ;o)

if it's a simple console app then I don't see why this is too much of a
problem... Anything beyond a few lines of code would merrit hooking in
events properly. But that said looking an instance where every x seconds
something happens, why not just have a while loop with a sleep anyway, with
no timers or events.

bool userSaysContinue = true;
while ( userSaysContinue )
{
Thread.Sleep( 1000 );
userSaysContinue =
MessageBox.Show( "Would you like to continue?", "Continue?",
MessageBoxButtons.YesNo ) == DialogResult.Yes;
}
 
If you only want your timer to continue to fire, use System.Threading.Timer
with a TimerCallback and block the calling thread with a ReadLine() or a
Join() call on the current thread.
(Note that Join will never return, so you need to CTRL-C).

class Tester
{
static void Main()
{
System.Threading.Timer stt =
new System.Threading.Timer(new TimerCallback(TimerProc), null, 1, 3000);
Thread.CurrentThread.Join();
// or wait for q to quit-> while(Console.Read()!='q');
}
static void TimerProc(Object stateInfo)
{
Console.WriteLine("Fired");
}
}

Willy.
 
Rather then Sleep, wake, check enabled, Sleep, wake, check enabled,
etc..
You can use a ManualResetEvent to signal the main thread when you have
disabled the timer and thread will only need to wake when the event is
signaled

class Foo
{
ManualResetEvent mExitEvent = new ManualResetEvent(false);
Timer mTimer = new Timer(1000);
...
void Run()
{
...
Timer.Start();
mExitEvent.WaitOne();
}
void TimerEvent(object source, ElapsedEventArgs e)
{
...
mTimer.Stop();
mExitEvent.Set();
}
}

- Kurt
 
That's pretty cool!

Kurt said:
Rather then Sleep, wake, check enabled, Sleep, wake, check enabled,
etc..
You can use a ManualResetEvent to signal the main thread when you have
disabled the timer and thread will only need to wake when the event is
signaled

class Foo
{
ManualResetEvent mExitEvent = new ManualResetEvent(false);
Timer mTimer = new Timer(1000);
...
void Run()
{
...
Timer.Start();
mExitEvent.WaitOne();
}
void TimerEvent(object source, ElapsedEventArgs e)
{
...
mTimer.Stop();
mExitEvent.Set();
}
}

- Kurt
 
Kurt said:
Rather then Sleep, wake, check enabled, Sleep, wake, check enabled,
etc..
You can use a ManualResetEvent to signal the main thread when you have
disabled the timer and thread will only need to wake when the event is
signaled

class Foo
{
ManualResetEvent mExitEvent = new ManualResetEvent(false);
Timer mTimer = new Timer(1000);
...
void Run()
{
...
Timer.Start();
mExitEvent.WaitOne();
}
void TimerEvent(object source, ElapsedEventArgs e)
{
...
mTimer.Stop();
mExitEvent.Set();
}
}

Alternatively, just use Monitor.Wait and Monitor.Pulse.
 
Hello,
Thanks to everyone who posted.
Incidentally, I found the ManualResetEvent solution most fitting.
Thanks again,
Aviv.
 
Hello,
Thanks to everyone who posted.
Incidentally, I found the ManualResetEvent solution most fitting.
Thanks again,
Aviv.
 
Back
Top