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!
Timers. Timer raises the elapsed event, is it raised in an independent thread? Yes, they run in a different thread. The System.
Timers. Timer is geared towards multithreaded applications and is therefore thread-safe via its SynchronizationObject property, whereas System. Threading.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With