Reputation: 853
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!
Upvotes: 9
Views: 2775
Reputation: 391664
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.
Upvotes: 10
Reputation: 43748
Maybe it just isn't in this code snippit, but do you ever decrement counter
?
Upvotes: 0