tmk1108
tmk1108

Reputation: 23

Timers and Garbage Collection

Say I have a class like this

class A
{
    private B _objB
    private Timer _timer; // Using System.Timers 

    public A(objB)
    {
        _objB = objB;
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += SomeEvent;
    }

    public void Begin()
    {
        _timer.start();
    }

    public void End()
    {
        _timer.Dispose();
    }

    public void SomeEvent (object sender, ElapsedEventArgs e)
    {
        if (_objB.Condition())
        {
            // do something
        }
        else 
        {
            _timer.Dispose();
        }
    }
}

Now somewhere else in my code in a different class I do this

public void SomeMethod(B objectB)
{
    A objA = new A(objectB);
    objA.Begin();
   // do other stuff
   // objA.End() can be called here but for this example it's not
}

I know that when I exit the scope of SomeMethod(), objA will won't be garbage collected because there is a timer event that keeps on firing. What I'm not sure about are the following:

1) When in SomeEvent, I hit the else condition and call _timer.Dispose(), this stops firing further events, but will this tell the GC that it can clean up the timer, and objA? In another words, am I causing any memory leaks?

2) Are there any race conditions that can cause exceptions? So like if I'm calling _timer.Dispose() and somehow have another timer event in queue, does entering that event causes any exceptions?

I'm just unsure if I'm doing right amount of cleaning up to avoid memory leaks.

Upvotes: 2

Views: 1140

Answers (1)

CharithJ
CharithJ

Reputation: 47540

  1. Generally correct. When you dispose Timer, ObjA will be eligible for GC. In fact, garbage collector will collect it during its next garbage collection cycle.

Keep in mind that, It will not collect your object immediately after it becomes eligible for GC. Garbage collector uses its heuristic algorithm to to trigger garbage collection. It occurs only when there is a memory pressure. In fact when Gen0 or Large Object Heap about to overflow.

  1. Possibly.. Have a look at here.

Callbacks can occur after the Dispose() method overload has been called, because the timer queues callbacks for execution by thread pool threads. You can use the Dispose(WaitHandle) method overload to wait until all callbacks have completed.

Upvotes: 1

Related Questions