7

我正在使用“Microsoft Minimal Rules”代码分析集构建我的项目,它在此方法上为我提供了 CA2000:

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;
}

System.Timers.Timer这个方法只是从一个以秒为单位的间隔创建一个新的。我有三个这样的计时器正在运行(每秒一个,每分钟一个和每半小时一个)。也许最好有一个计时器并检查经过的事件处理程序是否已经过了一分钟或半小时,但我不知道,此时这更容易,它是继承的代码,我不想破坏一切然而。

这种方法让我臭名昭著

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.

现在我正在调用 Dispose 并认为这就足够了?我还在班级自己的 IDisposable 实现中处理所有计时器。

我在这里想念什么?

4

4 回答 4

2

您只Dispose在出现异常的情况下调用(BTW 永远不应该使用 catch-all 块来处理,但那是另一回事了)。在没有例外的情况下,您不处置该Timer对象。

添加一个finally块并将其移动到Dispose那里,或使用一个using块。

于 2012-05-22T07:27:14.670 回答
1

该警告告诉您,您正在创建一个一次性对象,而不是在所有情况下都将其丢弃。如果您以其他方法正确处理它,那么您可以安全地抑制此警告(您可以使用SuppressMessageAttribute来做到这一点)。

于 2012-05-22T07:29:42.893 回答
1

好的,我这样编辑它:

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;
    }

这是根据 CA2000 文档,它没有给出警告。我忽略了一个事实,即对象初始值设定项语法会创建一个可能不会被释放的临时对象。

多谢你们!

于 2012-05-22T07:42:42.387 回答
-1

我认为使用“使用”而不是“尝试/最终”参考要好得多

private Timer InitializeTimer(double intervalInSeconds)
{
    Timer timer;
    using (var tempTimer = new Timer())
    {
        tempTimer.Interval = intervalInSeconds * 1000;
        tempTimer.Enabled = true;
        tempTimer.Elapsed += timer_Elapsed;
        tempTimer.Start();
        timer = tempTimer;
    }
    return timer;
}
于 2014-10-29T16:45:54.543 回答