Timer callback blocks other timers

I have a Little Problem with timers in my Project.

I use multiple timers (System.Threading.Timer).
Some of the TimerCallback methods are short running, some are long running.
Now I found out that as long as the long running timer callback is executed, no other timer is fired.
Is this normal behaviour in NETMF or is there a maximum limit of timer callbacks which are executed in parallel.
For testing issues I started the long running operation in a seperate thread from the original timer callback.
After this change the short running timer is executed normally

longRunningTimer = new Timer(LongRunningCallback, null, 30000, 30000);
shortRunningTimer = new Timer(ShortRunningCallback, null, 1000, 1000);

...
void LongRunningCallback(object state)
{
   // this is a longer operation which blocks other timers
   Thread.Sleep(20000);
}

void ShortRunningCallback(object state)
{
   // I'm done quickly
   Thread.Sleep(50);
}

If i Change the LongRunningCallback to

void LongRunningCallback(object state)
{
   ThreadPool.QueueUserWorkItem(_ =>
     {
         // this is a longer operation which does not blocks other timers
         Thread.Sleep(20000);
      });
}

It works fine and the 1000ms Timer is fired all the time.

I’m using the latest SDK 4.2.11 on a G120
And just to mention: I’m not sure if this is a general problem or if this just happens in my quite huge multi threaded application.

These are timers, why do you use Thread.Sleep() in the callbacks?

Oh, my bad, misread your post :slight_smile:

Anyway, you are putting the thread to sleep. Both timers are constructed on the same thread, so if you are instructing one timer to sleep, the whole thread sleeps… At least I think so.

This is just sample code.
My real callbacks do real work.
The long running operation provides a file via FTP and waits with a ManualResetEvent until someone stores some other file via FTP.
This is done every 30 sec. and usually takes 10 to 15 sec.

@ Simon from Vilnius - So you think all timers are fired from one single thread?
If it is like this, then this would explain this behaviour.
The docs say that a thread pool is used for the timer, but this might just be copy/paste from the Win .net docs.

I think timers use the same thread

I’ll try to figure this out tomorow. The managed thread id should tell me.

Sounds logical.

I would not be surprised if the timers use the same thread as the managed hardware interrupts.

In general, it is better not do any serious processing in a handler of a framework event.

Well, that’s what I made my ThreadPool for :wink:
https://www.ghielectronics.com/community/codeshare/entry/806

Sounds like yu have the perfect application for your thread pool. ;D

the documentation is a bit vague. it implies a thread pool, and says the thread is not the one that created the timer. it does not say how many threads are in the pool, and whether multiple timer events are run concurrently.

like many things in MF, you have to try it to get a real answer.

@ andre.m -

Usually this is done with GUI programs because they want you to make any changes to the controls on the thread that created them. A guess this is a way of single threading GUI changes.

A thread is being used in a timer callback. One of the secret threads in MF.

All timer callbacks run on a single shared thread.

@ Architect - Do you know if it the same thread as the hardware interrupts?

@ Mike - Can’t tell at the moment, have to look at the PK code.

Well, I guess thats the answer to my question.
I’ll place an issue at NETMF.
Calling a single thread a ‘thread pool’ is a bit irritating.

Just now I found the answer in the comments of the online docs:
Go to Timer Class | Microsoft Learn and scroll fully down, then you see:

[quote]No thread pool :
As of at least .NET MF 4.2, thread pooling has not been implemented. All TimerCallback’s run on a single shared (automatically created) thread, and so are all serialized with respect to one another. Futhermore, periodic timers (if used) are not rescheduled until after their corresponding TimerCallback has returned. [/quote]

1 Like