Posts By Category

Posts By Date

Resources:

C# Books
ASP.NET Books DotNet4All








If you like to support this site, feel free to make a donation to support improvements.

Thank you!

Monetize Your Blog

System.Windows.Forms.Timer does not work for Console Applications because you need an event loop, so you need to use System.Threading to implement your own timer with an event loop, here is how...

In Console Applications, you don't have an event message loop like in a Windows Application project, hence, so you can't use the System.Windows.Forms.Timer object since it depends on Windows Message loop to fire its tick events.

Instead, you will need to write your own timer object using multi-threading in C#. In this article I describe just how to write your own Timer for your Console Application.

First you need to build your own timer class object. To start, we can do something like this:

    class Timer

    {

        // Delegates

        public delegate void Tick();

 

        // Properties

        public int Interval;

        public Tick OnTimerTick;

 

        // Private Data

        Thread _timerThread;

        volatile bool _bStop;

    }

 

Next you want to implement an event loop for the timer. This code will run on the timer's thread, not the main thread. Here is how you'd write one:

 

    public void Run()

    {

        while (!_bStop)

        {

            // Sleep for the timer interval

            Thread.Sleep(Interval);

            // Then fire the tick event

            OnTimerTick();

        }   

    }

 

A Timer has a Start & Stop methods. These methods run on the main thread, and control the timer's operation. The above timer event loop however runs on a separate worker thread, which is created in the Start method implementation as follows:

 

    public Thread Start()

    {

        _bStop = false;

        _timerThread = newThread(newThreadStart(Run));

        _timerThread.IsBackground = true;

        _timerThread.Start();

        return _timerThread;

    }

Now to stop the Timer, we'll need to set the volatile boolean in the Timer data members to false. The Stop Method is invoked from the main thread. The value of the volatile member is then checked each time in the event loop of the worker thread (as seen above). Here is how to implement the Stop method for the timer:

    public void Stop()

    {

        // Request the loop to stop

        _bStop=true;

    }

Notice that the stop method would only put a request to stop the timer, but won't kill the thread. If the timer interval is short, that isn't much of a problem, but if the timer interval is long, say 5 minutes, it might take the whole 5 minutes before the timer checks the above volatile member and decides to stop the event loop. To fix this, there are 2 options, first is to simply kill the worker thread in the Stop implementation (remember the Stop method is invoked on the main thread), as follows:

    public void Stop()

    {

        // Request the loop to stop

        _bStop=true;

        _timerThread.Join(1000);

          _timerThread.Abort();

    }

A better way however is to sleep intermittently in the event loop and check the volatile member more frequently:

    public void Run()

    {

        while (true)

        {

            // Sleep for the timer interval

            SleepIntermittently(Interval);

            // Then fire the tick event

            OnTimerTick();

        }

    }

Now you can just implement the Stop method as before. Here is the implementation of the SleepIntermittently method:

    public void SleepIntermittently(int totalTime)

    {

        int sleptTime = 0;

        int intermittentSleepIncrement = 10;

        while (!_bStop && sleptTime < totalTime)

        {

            Thread.Sleep(intermittentSleepIncrement);

            sleptTime += intermittentSleepIncrement;

        }

    }

Finally here is a test application for our Console timer:

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

 

namespace TimerConsoleApp

{

    class Program

    {

        public static void timerTick()

        {

            Console.WriteLine("[W] Timer Ticked!");

        }

 

        static void Main (string[] args)

        {

            Timer timer = newTimer();

            timer.Interval=500;

            timer.OnTimerTick += timerTick;

            Thread timerThread = timer.Start();

 

            for (int i = 0; i < 10; i++)

            {

                if (i > 5)

                {

                    Console.WriteLine("[M] Timer is Stopped! " + DateTime.Now.ToLongTimeString());

                }

                 else

                {

                    Console.WriteLine("[M] Timer is Active! " + DateTime.Now.ToLongTimeString());

                }

 

                if (i == 5)

                {

                    Console.WriteLine("[M] Stopping the timer...");

                    timer.Stop();

                }

 

                // Do lengthy main thread processing here

                ///

                Thread.Sleep(5000);

            }

        }

    }

}

And now the timer is ready for use.

Happy Programming!

Demo (You will need .NET 2.0 installed run this app)

kick it on DotNetKicks.com

Feedback

Posted on 5/13/2010 12:43:26 PM

Doesn't work. Can you post the source code? Lots of snippets here...

Posted on 1/13/2010 8:30:51 AM

I like this web material it is very good web for programing.

Posted on 1/21/2009 9:22:25 AM

Thanks for the Timer Class. Just what I needed for a server console app running telcom records collection process. Yes there are other ways to do it if your running an ASPX (system.threading.timer) but for a standalone console app this fits the bill. Quick and fast, up and running in less than 5 mins. Again.. thanks.

Posted on 7/1/2008 5:46:00 AM

Hi Simas,

Yes, I believe that is true, since the timer tick function is running on the main thread, it will hold up the whole app which will prevent firing up any more timer events.

It is best however to send the lengthy calculation to a System.Components.BackgroundWorker, which can be fired from the timer event processor asynchronously, and so the timer event handler can return immediatly, keeping a smooth GUI operation while the background worker takes care of the lengthy processing.

Posted on 7/1/2008 5:38:26 AM

Ok, what if our timerTick() does some large scale rendering which takes 5 seconds to complete. Then timer ticking interval will be Timer.Interval + rendering time, right?

Posted on 4/5/2007 2:06:51 PM

I agree! It’s better to use tested code than write your own :) but I'll keep it up though as a tutorial / exercise like you said.

One reusable piece in my timer class is the SleepIntermittently method. It can be reused in other multi-threaded projects to make the application more responsive to user commands.

Thanks for the comment... keep them coming! :-)

Posted on 4/5/2007 12:53:58 PM

Although writing your own timer class is a good excercise. There are a couple of other timer options in .NET 2.0

System.Threading.Timer, This is a Server timer that you pass a callback to when you new it up.

System.Timers.Timer, This is a thread based timer that you set a handler for the elapsed event.

Might save some time and debugging :)

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Enter the text you see in the box:
 


Copyright © 2007 Yousef Mannaa. All material on this site is copyrighted.
Do not publish or reproduce any of this material without written permission from the Author