KansaiRobot
KansaiRobot

Reputation: 9912

Timer (Calling Elapsed function several times)

I am using a System.Timers.Timer with a function set to Elapsed. 'aTimer.Elapsed+=OnTimedEvent` set to fire periodically at regular times. Let's say this happens every 5 seconds.

What happens if for some reason the processing of OnTimedEvent last more than 5 seconds.

According to the documentation, * the event might be raised again on another ThreadPool thread. In this situation, the event handler should be reentrant.*

Although I understand somehow this in theoretical terms, can someone explain this to me in easier and practical terms?


If it helps in my onTimedEvent I am trying to read from a NetworkStream.

Upvotes: 0

Views: 765

Answers (1)

CodingYoshi
CodingYoshi

Reputation: 27009

In simple terms it means: The OnTimedEvent should be able to support multiple threads going through it at the same time. Why? Because while your method is executing, if you do not stop the timer, it will fire again in 5 seconds. But this time it will fire on another thread since the first thread is busy executing the first call. Therefore, a second thread will enter the method. At this point, if OnTimedEvent is not thread safe, bad things can happen.

You can google more about supporting multiple threads and you should be able to find plenty information.

Most of the time, people stop the timer while the method is executing and then restart it at the end of the method. But this depends on your requirements and what it is that you are doing.

Here is an example of a NON re-entrant method:

static int sum = 0;

int increment(int i) {
    sum += i;
    return sum;
}

It is not reentrant because if T1 is inside the method executing it and adds 1 to the sum, sum will become 1. If it is interrupted, meaning execution control is taken at this point and given to T2, when T2 comes the value of sum will not be 0 but 1. T2 will add 1 to sum and return 2. When T1 comes back it will continue from where it left off i.e. it has already done addition so it will just return 1. Thus the 2 threads left with different result: T1 with 1, T2 with 2. Therefore, the method is not re-entrant.

To make it re-entrant, we simply do this:

int increment(int sum, int i) 
{
    return sum + i;
}

Now each thread will return with the same answer even if they leave in the middle of the method execution since all the variables are on the stack and not shared by threads (each thread will have its own copy of the variables).

This SO answer has great information and explanation if you want to read more.

Upvotes: 2

Related Questions