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?


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.


The warning tells you that you are creating a disposable object and not disposing it in all cases. If you are properly disposing it in some other method, then you can safely suppress this warning (you can do that using the SuppressMessageAttribute).


Okay, I edited it like this:

private Timer InitializeTimer(double intervalInSeconds)
    {
        Timer tempTimer = null;
        Timer timer;
        try
        {
            tempTimer = new Timer();
            tempTimer.Interval = intervalInSeconds * 1000;
            tempTimer.Enabled = true;
            tempTimer.Elapsed += timer_Elapsed;
            tempTimer.Start();
            timer = tempTimer;
            tempTimer = null;
        }
        finally
        {
            if (tempTimer != null)
            {
                tempTimer.Dispose();
            }
        }
        return timer;
    }

This is per the CA2000 docs and it doesn't give a warning. I had overlooked the fact that the object initializer syntax creates a temporary object which may not be disposed.

Thanks, guys!

链接地址: http://www.djcxy.com/p/10804.html

上一篇: 隐藏元素与可见:后

下一篇: 为什么此方法会导致代码分析错误CA2000:Call Dispose()