2
votes

In my project i created System.Timers.Timer object and the interval is set to 10 min. For every 10 min I am getting elapsed event. In this event handler i am executing some code.

Before executing this code I am setting Enabled property equal to false because if the handler takes longer to execute than the next interval another thread executes the elapsed event.

Problem here is suddenly Elapsed event is stopped.

I have read some articles and suspecting that the moment enabled property set to false garbagecollector frees the timer object.

If it is right please tell me the solution.

Below is example code:

public class Timer1
{
    private static System.Timers.Timer aTimer;

    public static void Main()
    {
        // Create a timer with a ten second interval.
        aTimer = new System.Timers.Timer(10000);

        // Hook up the Elapsed event for the timer.
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

        // Set the Interval to 10min.
        aTimer.Interval = 600000;
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program.");
        Console.ReadLine();
    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        aTimer.Enabled = false;

        // excutes some code

        aTimer.Enabled = true;
    }
}
2
What is the link for that article? It sounds incorrect for me. What a reason for GC to collect still referenced object with property set to some value? This is very uncommon behavior of GC in .NET - abatishchev
Thanks for your answer. Please look at the below logs which are states that "when Enabled property set it to false its marked for GC,so it could free the resources held by the timer" forums.codeguru.com/printthread.php?t=342524 kvarnhammar.blogspot.com/2008/12/… stackoverflow.com/questions/14617336/… stackoverflow.com/questions/14216098/… - user2080185

2 Answers

3
votes

Since you have a field in your class pointing to your timer object, the GC will not collect the timer object.

But your code may raise exception, and this can prevent the Enabled property to become true again. To guard agianst this, you should use a finally block:

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    aTimer.Enabled = false;
    try
    {
        // excutes some code
    }
    catch(Exception ex)
    {
        // log the exception and possibly rethrow it
        // Attention: never swallow exceptions!
    }
    finally
    {
        aTimer.Enabled = true;
    }
}
0
votes

You can set synchronization object, in that case the elapsed will happen only on the owner thread of that object, with no concurrency. A similar question is posted here: Do C# Timers elapse on a separate thread?