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、秒単位の間隔から新しいものを作成するだけです。このようなタイマーを 3 つ実行しています (1 秒ごと、1 分ごと、30 分ごと)。タイマーを 1 つ用意して、経過イベント ハンドラーで 1 分または 30 分が経過したかどうかを確認する方がよいかもしれませんが、現時点ではこれの方が簡単です。継承されたコードであり、すべてを壊したくありません。まだ。

この方法は私に悪名高い

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ます(キャッチオールブロックで処理することはできませんが、それは別の話です)。例外なしの場合、Timerオブジェクトを破棄しません。

ブロックを追加してそこにfinally移動するか、ブロックをDispose使用しusingます。

于 2012-05-22T07:27:14.670 に答える
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

警告は、使い捨てオブジェクトを作成していて、すべての場合にそれを破棄していないことを示しています。他の方法で適切に破棄している場合は、この警告を安全に抑制することができます ( SuppressMessageAttributeを使用してこれを行うことができます)。

于 2012-05-22T07:29:42.893 に答える
-1

「try/finally」リファレンスではなく「using」リファレンスを使用する方がはるかに優れていると思います

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 に答える