System Threading Timer in C# Explained With Examples - Owlcation - Education
Updated date:

System Threading Timer in C# Explained With Examples

Author:

I am a software engineer. I have been working with C++, MFC, and .net technologies for 15 years. I like video games and reading books.

1. Introduction

A “Timer” is a trigger which fires a particular function periodically. This regular interval is controllable and one can specify it during the Timer creation or even can change it after creating the timer.

Dot Net Framework supports three kinds of timers. They are:

  1. A Timer Component from Forms
  2. A Timer Class from the Threading
  3. A Timer from Timer Namespace itself

The Timer Component from the Windows Forms Namespace is useful when we want to run a function at a regular interval. Moreover, this function can have liberty of accessing the User Interface elements. Although this may be true, the only constraint is that the Timer Component should belong to the Same UI thread.

The Timer Component from the Timer name space if useful when we want to achieve the Mixture of UI and System Tasks. Besides, The Timer from System.Threading Namespace is useful for running a background task without disturbing User Interface. In this article, we will look at System.Threading.Timer in detail with an Example.

2. Constructing the Timer

The Timer depends on four information for its operation. They are:

  1. Timer Callback
  2. State Object
  3. Due Time
  4. Timer Interval

“Timer Callback” is a method and the Timer calls it at regular interval of time. The “State” object is useful for providing the additional information required for the Timer operation. However, this State object is not mandatory and hence we can set it as null while constructing the Timer object. Now, have a look at the below depiction:

Timer Callback and Timings

Timer Callback and Timings

The “Timer Interval” specifies a time in milliseconds and when that time elapses, the Timer Callback routine gets called. We can use "Due Time" to specify a delay or wait after the Timer creation. For Example, if a Delay Time is 2000 Milliseconds, then after the Timer creation, it will wait for 2 seconds before calling the Timer Callback. Unlike the Windows Forms’ Timer, the Threading Timer will invoke the Timer Callback in different thread

3. The Threading Timer Example

3.1 Preparation

First, we include required Namespace for the example. The Timer we will deal is from Threading Namespace and hence we included that Namespace. The code is below:

//Sample 01: Include required Namespace
using System.Threading;

Next, we declare the Timer object. Later, we will construct it in the program main based on the user input through Console Window. We are also storing the foreground color of the console output window. We will use it to reset the console window after the example competes the program execution. The code is below:

//Sample 02: Declare the Timer Reference
static Timer TTimer;
static ConsoleColor defaultC = Console.ForegroundColor;

3.2 Timer Callback Function

The Timer instance will call a specific function at a regular interval of time. This function is known as “Timer Callback”. It should return void and should take object as parameter to qualify as Timer Callback. Application developers usually place the periodic running task in it.

//Sample 03: Timer Callback - 
//  Just Ticks in the Console
static void TickTimer(object state)
{
    Console.Write("Tick! ");
    Console.WriteLine(
        Thread.CurrentThread.
        ManagedThreadId.ToString());
    Thread.Sleep(500);
}

In the above Timer Callback, we are printing two messages to the console output window. One is the string Tick! and other one is the thread id in which the Callback function is running. We also make our Callback halt the execution for about half of a second using the function call Sleep.

3.3 Create and Start the Timer

As we already know, we create our Timer using the Threading Namespace. Below is the code which creates the Timer instance and stores that in "TTimer" reference:

//Sample 04: Create and Start The Timer
TTimer = new Timer(
    new TimerCallback(TickTimer), 
    null, 
    1000, 
    1000);

We are passing the "TimerCallback" delegate as first parameter which points our Callback function . The second parameter is null as we do not want to track any object state. We are passing 1000 as third parameter which tells the Timer to wait for one second after its creation. This third parameter is what called “Due Time” or “Delay Time”. Finally, we are passing 1000 as fourth parameter which sets the regular interval for invoking the Callback function. In our example, since we pass 1000 as parameter the Callback function gets called for every single second.

3.4 Stopping the Timer

One can use the “Change()” function on the Timer class to stop it. Have a look at the below code:

//Sample 05: Stop The Timer
TTimer.Change(
    Timeout.Infinite,
    Timeout.Infinite);

In the above code, we are stopping the Timer by setting the Due Time and Period with “Timeout.Infinite” constant. This method call stops the Timer but at the same time currently running Timer Callback continues its execution and exits normally. Stopping the Timer means we stop periodic trigger that calls the Timer Callback.

All right! Now let us have a look at the complete Console Application which is given below:

using System;
using System.Collections.Generic;
using System.Text;

//Sample 01: Include required Namespace
using System.Threading;

namespace ThreadTimer
{
    class Program
    {
        //Sample 02: Declare the Timer Reference
        static Timer TTimer = null;
        static ConsoleColor defaultC = 
            Console.ForegroundColor;

        //Sample 03: Timer Callback - 
        //  Just Ticks in the Console
        static void TickTimer(object state)
        {
            Console.Write("Tick! ");
            Console.WriteLine(
                Thread.CurrentThread.
                ManagedThreadId.ToString());
            Thread.Sleep(4000);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Press R to Start the Timer "
                +"Press H to Stop the Timer"
                + Environment.NewLine);
            while (true)
            {
                ConsoleKeyInfo key = Console.ReadKey();
                if (key.KeyChar == 'R' || 
                    key.KeyChar == 'r')
                {
                    Console.ForegroundColor = 
                        ConsoleColor.Yellow;
                    Console.WriteLine(
                        Environment.NewLine +
                        "Starting the Timer" +
                        Environment.NewLine);
                    //Sample 04: Create and Start The Timer
                    TTimer = new Timer(
                        new TimerCallback(TickTimer), 
                        null, 
                        1000, 
                        1000);
                }
                else if (key.KeyChar == 'H' || 
                    key.KeyChar == 'h')
                {
                    Console.ForegroundColor = defaultC;
                    if (TTimer == null)
                    {
                        Console.WriteLine(
                            Environment.NewLine +
                            "Timer Not " +
                            "Yet Started" +
                            Environment.NewLine);
                        continue;
                    }
                    Console.WriteLine(
                        Environment.NewLine +
                        "Stopping the Timer" +
                        Environment.NewLine);
                    //Sample 05: Stop The Timer
                    TTimer.Change(
                        Timeout.Infinite,
                        Timeout.Infinite);
                    break;
                }
            }
        }
    }
}

4. The Timer Callback Runs on ThreadPool

Once we execute the example, it opens a console windows and waits for the user input to start the Timer. The Console window is shown below:

Console window waits to start Timer

Console window waits to start Timer

Note that, in the Timer Callback function, we are printing the Thread Id, after printing the message “Tick!”. Once we press the “R” or “r” in the keyboard, the Timer gets created and waits for 1000 Milliseconds (1 Second) Due Time and then triggers our Callback function. For this reason, we see our first message with 1 second delay.

After this, we see the “Tick!” printed periodically in the console window. In addition, we also see the Thread number get printed in the console window. To halt the Timer, we have to either press “H” or “h” key in the console window. Before we go further, look at the depiction below:

Timer Callback Executed Single Thread

Timer Callback Executed Single Thread

In the Callback function we set a delay of 500 Milliseconds and also set Periodic Interval of the Timer as 1000 Milliseconds. Where is the Thread Pool? Why we see only one Thread when executing the Timer?

First thing to remember is that a Thread is nothing but a parallel execution of a code segment. The second thing is our Timer Finishes the task in 500 Milliseconds (Skipping the overhead of console print) and the Regular Interval of the Timer is 1000 Milliseconds. Hence, there is no possibility of two Callback routine running in parallel. As a result, Thread Pool uses the same Thread from its Thread collection (Pool) to run the Callback.

Now let us make a simple change in the Timer Callback. We will increase the Callback execution time by introducing more delay (4000 Milliseconds) and experiment how the Callback is executed with same Periodic Interval of 1000 Milliseconds. Since, it takes 4 seconds to execute the Callback and at the same time Timer tick happens for every 1 second, we will see the Thread Pool allocating different threads for the Callback function.

This change is shown here:

//Sample 03: Timer Callback - 
//  Just Ticks in the Console
static void TickTimer(object state)
{
    Console.Write("Tick! ");
    Console.WriteLine(
        Thread.CurrentThread.
        ManagedThreadId.ToString());
    Thread.Sleep(4000);
}

The output of the Program is shown below:

Callback on the ThreadPool

Callback on the ThreadPool

The above output proves that the Callback is executing on the Thread pool. We can see FourThreads (Ids: 4,5,6,7) executing in parallel as the Timer Interval is 1 Second and Execution Time for Callback is 4 Seconds.

© 2018 sirama

Comments

A Developer on August 27, 2020:

Thanks for this valuable article.

Dale Hays on July 24, 2020:

Nice article . . . straight forward and helped me get this simple timer implemented. Thanks!

Related Articles