Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this method cause Code Analysis error CA2000: Call Dispose()

I'm building my project with the "Microsoft Minimal Rules" code analysis set and it gives me CA2000 on this method:

private Timer InitializeTimer(double intervalInSeconds)
{
    Timer timer = null;

    try
    {
        timer = new Timer { Interval = intervalInSeconds * 1000, Enabled = true };
        timer.Elapsed += timer_Elapsed;
        timer.Start();
    }
    catch
    {
         if (timer != null)
         {
             timer.Dispose();
         }
    }
    return timer;
}

This method just creates a new System.Timers.Timer from an interval in seconds. I have three such timers running (one for every second, one every minute and one every half hour). Maybe it's better to have one timer and check in the elapsed event handler whether a minute or a half hour has passed, but I don't know, this is easier at this time, it's inherited code and I don't want to break everything yet.

This method gives me the infamous

Warning 21  CA2000 : Microsoft.Reliability : In method 'TimerManager.InitializeTimer(double)', call System.IDisposable.Dispose on object '<>g__initLocal0' before all references to it are out of scope.

Now I AM calling Dispose in the catch and thought this would be enough? I'm also disposing all timers in the class' own IDisposable implementation.

What am I missing here?

like image 450
Davio Avatar asked May 22 '12 07:05

Davio


People also ask

When the Dispose method is called?

It only occurs when there are objects in the Finalization Queue. It only occurs when a garbage collection occurs for Gen2 (which is approx 1 in every 100 collections for a well-written . NET app).

Is Dispose method called automatically?

Dispose method must be called explicitly, objects that implement IDisposable should also implement a finalizer to handle freeing resources when System. IDisposable. Dispose is not called. By default, the garbage collector will automatically call an object's finalizer prior to reclaiming its memory.

What keyword calls IDisposable dispose?

NET calls an IDisposable object's Dispose() method once the code exits the block.


1 Answers

You only call Dispose in case of an exception (which you should never handle with a catch-all block BTW, but that is another story). In case of a no exceptions, you don't dispose the Timer object.

Either add a finally block and move the Dispose there, or use a using block.

like image 130
Christian.K Avatar answered Oct 05 '22 00:10

Christian.K