2

ロギング システムをリセットするメソッドを作成しています。CsvFileLogWriter (カスタム クラス) のインスタンスを取得し、それをリセット メソッドに渡す必要があります。CsvFileLogWriter は使い捨てなので、CA2000 の警告が表示されます。

Warning 2   CA2000 : Microsoft.Reliability : In method 'Logger.InitializeCsvLogger
(string)', call System.IDisposable.Dispose on object 'tempWriter'
 before all references to it are out of scope.

CA2000に関連する指示に従いましたが、最終的に次の方法になりました。ただし、まだ CA2000 警告が表示されます。

public static void InitializeCsvLogger(string path)
{
    ILogWriter tempWriter = null;

    try
    {
        tempWriter = new CsvFileLogWriter(path);
        ResetWriter(tempWriter);
        tempWriter = null;
    }
    finally
    {
        if (tempWriter != null)
            tempWriter.Dispose();
    }
}

誰かが私の間違いを見つけてもらえますか?

編集

tempWriterによって参照されているライターを破棄したくありません。これは一時的なオブジェクトではなく、単なる一時的な参照です。try ブロック内で障害が発生した場合にのみ破棄します (したがって、tempWriterが null に設定されることはなく、finally ブロックの if ステートメントによってリソースがクリアされます)。この障害が発生しない限り、tempWriterを破棄したくありません。オブジェクト自体は、ResetWriter(tempWriter)によってプロパティに設定された後も引き続き使用する必要があります。これは、CA2000 の規則によるものです。http://msdn.microsoft.com/en-us/library/ms182289.aspx?queryresult=true を参照してください。

明確にするために、ResetWriterの機能を次に示します。Writerは静的プロパティです。このメソッドは古いライターを破棄し、新しいライターを設定します。

private static void ResetWriter(ILogWriter newWriter)
{
    if (Writer != null)
        Writer.Dispose();
    Writer = newWriter;
}

編集

SLaksが述べたように、それは誤検知だと思います。ResetWriter の内容を取得し、それらを ResetWriter の呼び出しの代わりに配置すると (本質的に抽出メソッドのリファクタリングが逆になります)、CA2000 は消えます。

つまり、次の場合、CA2000 警告は表示されません。

public static void InitializeCsvLogger(string path)
{
    ILogWriter tempWriter = null;

    try
    {
        tempWriter = new CsvFileLogWriter(path);
        if (Writer != null)
            Writer.Dispose();
        Writer = tempWriter;
        tempWriter = null;
    }
    finally
    {
        if (tempWriter != null)
            tempWriter.Dispose();
    }
}
4

3 に答える 3

3

nullに割り当てる場合tempWriter:

tempWriter = null;

tempWriterは、作成したオブジェクトを参照しなくなりました。したがって、オブジェクトを破棄する方法はありません。

この場合、代わりに using ブロックを実際に使用する必要があります。

using(var tempWriter = new CsvFileLogWriter(path))
{
    ResetWriter(tempWriter);
}

これにより、Dispose の呼び出し (または参照を null に設定) について心配する必要がなくなります。

于 2011-11-07T16:39:42.930 に答える
2

この警告は誤検知です。

コード分​​析エンジンは、ライターが生き続ける必要があることを認識していないためResetWriter、あらゆる状況でライターを破棄する必要があります。

警告を抑制する必要があります。

于 2011-11-07T16:57:27.060 に答える
2

ブロックはその後にのみ実行されるため、書き込むtempWriter = nullことで、ブロックが破棄されるのを防ぎます。finally

using代わりにステートメントを使用する必要があります。

この答えは正しいですが、実際の意図と矛盾しています

于 2011-11-07T16:38:17.497 に答える