Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Threading.Timer not continuous

I am having troubles with creating a continuous timer. There are multipule staggered threads created on timers which will run for some time then come to a complete stop. The maximum threads I am allowing is 5 and the timer interval is set to 10000. So in theory there would be 1 thread executed every 2 seconds.

This happens for a while, but then it stops. currently I am testing in a console app and writing the responses to the app.

I am not exactly sure what is happening here

internal class EngineThreadGenerator
{
    private readonly AutoResetEvent _autoEvent;
    private readonly Action<string, string> _processQueueDelegate;
    private readonly Action<string, string> _purgeQueueDelegate;

    private void createAllowedEmailThreads()
    {
        for (int counter = 0; counter < AppSettings.ProcessQueueAllowedThreads; counter++)
        {
            EmailThread _emailThread = new EmailThread(_collection, _processQueueDelegate, _purgeQueueDelegate);
            TimerCallback _timerCallback = _emailThread.InitEmailThread;
            Timer _stateTimer = new Timer(_timerCallback, _autoEvent, 0, AppSettings.ProcessIntervalInMilliseconds);

            pauseLoop();
        }
    }

Any help here is greatly appreciated! Cheers!

like image 576
BoredOfBinary Avatar asked May 05 '11 18:05

BoredOfBinary


People also ask

Does System timers timer run in a separate thread?

Timers. Timer raises the elapsed event, is it raised in an independent thread? Yes, they run in a different thread. The System.

Is System timers timer thread-safe?

Timers. Timer is geared towards multithreaded applications and is therefore thread-safe via its SynchronizationObject property, whereas System. Threading.

What is System threading timer?

The Timer class (in the System. Threading namespace) is effective to periodically run a task on a separate thread. It provides a way to execute methods at specified intervals. This class cannot be inherited. This class is particularly useful for developing console applications, where the System.

What is the difference between thread and timer?

As we see above, Thread is the implementation that does the heavy lifting, and Timer is a helper that adds extra functionality (a delay at the front); Timer(0, func) wouldn't work if Thread didn't exist.


1 Answers

The reason your timers are dying after 3 minutes is that you have a lot of memory available.

Which means the garbage collector takes about 3 minutes to get to your objects before collecting them.

You're supposed to keep a reference to the timer for the duration of its lifetime. Since you're not doing that, the timer is eligible for garbage collection as soon as your loop ends.

3 minutes later, or whenever GC gets around to it, the timer is collected, and your code stops executing.

So, keep a reference to the timer object, and you should be all set.

Here's a simple LINQPad script to test with:

void Main()
{
    new Timer(Callback, null, 0, 1000);
    Thread.Sleep(5000);
    Debug.WriteLine("collecting");
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    Debug.WriteLine("collected");
    Thread.Sleep(5000);
}

static void Callback(object state)
{
    Debug.WriteLine("callback");
}

Observe that once the main thread runs GC, the callback stops. If, on the other hand, you make a copy of the timer into a field:

Timer _Timer;

void Main()
{
    _Timer = new Timer(Callback, null, 0, 1000);
    ...

the timer keeps on ticking past GC.

like image 114
Lasse V. Karlsen Avatar answered Oct 14 '22 03:10

Lasse V. Karlsen