次の方法で共有


streamWriterBufferedDataLost MDA

この記事は .NET Framework に固有のものです。 .NET 6 以降のバージョンを含む、.NET の新しい実装には適用されません。

StreamWriterが書き込まれると、streamWriterBufferedDataLostマネージド デバッグ アシスタント (MDA) がアクティブになりますが、StreamWriterのインスタンスが破棄される前に、Flushまたは Close メソッドは呼び出されません。 この MDA が有効になっている場合、ランタイムは、バッファーに格納されたデータが StreamWriter内にまだ存在するかどうかを判断します。 バッファー内のデータが存在する場合は、MDA がアクティブになります。 CollectメソッドとWaitForPendingFinalizersメソッドを呼び出すと、ファイナライザーを強制的に実行できます。 それ以外の場合、ファイナライザーは一見任意の時間に実行され、プロセスの終了時には実行されない可能性があります。 この MDA を有効にしてファイナライザーを明示的に実行すると、この種の問題をより確実に再現するのに役立ちます。

Symptoms

StreamWriterでは、最後の 1 ~ 4 KB のデータはファイルに書き込まれません。

原因

StreamWriterはデータを内部的にバッファー処理するため、バッファーに格納されたデータを基になるデータ ストアに書き込むには、CloseまたはFlush メソッドを呼び出す必要があります。 CloseまたはFlushが適切に呼び出されない場合、StreamWriter インスタンスにバッファーされたデータが想定どおりに書き込まれていない可能性があります。

次に、この MDA でキャッチする必要がある、不適切に記述されたコードの例を示します。

// Poorly written code.
void Write()
{
    StreamWriter sw = new StreamWriter("file.txt");
    sw.WriteLine("Data");
    // Problem: forgot to close the StreamWriter.
}

上記のコードは、ガベージ コレクションがトリガーされ、ファイナライザーが完了するまで中断された場合に、この MDA をより確実にアクティブ化します。 この種の問題を追跡するには、デバッグ ビルドで前のメソッドの末尾に次のコードを追加します。 これはMDAを確実にアクティブ化するのに役立ちますが、もちろん問題の原因は解決しません。

GC.Collect();
GC.WaitForPendingFinalizers();

Resolution

アプリケーションまたはStreamWriterのインスタンスを含むコード ブロックを閉じる前に、StreamWriterCloseまたはFlushを呼び出してください。 これを実現するための最適なメカニズムの 1 つは、C# using ブロック (Visual Basic でUsing ) を使用してインスタンスを作成することです。これにより、ライターの Dispose メソッドが呼び出され、インスタンスが正しく閉じられます。

using(StreamWriter sw = new StreamWriter("file.txt"))
{
    sw.WriteLine("Data");
}

次のコードは、usingではなくtry/finallyを使用する同じソリューションを示しています。

StreamWriter sw;
try
{
    sw = new StreamWriter("file.txt"));
    sw.WriteLine("Data");
}
finally
{
    if (sw != null)
        sw.Close();
}

どちらのソリューションも使用できない場合 (たとえば、StreamWriterが静的変数に格納されていて、有効期間の終了時にコードを簡単に実行できない場合)、最後に使用した後にStreamWriterFlushを呼び出すか、AutoFlush プロパティを最初に使用する前にtrueに設定すると、この問題を回避できます。

private static StreamWriter log;
// static class constructor.
static WriteToFile()
{
    StreamWriter sw = new StreamWriter("log.txt");
    sw.AutoFlush = true;

    // Publish the StreamWriter for other threads.
    log = sw;
}

ランタイムへの影響

この MDA はランタイムには影響しません。

アウトプット

この違反が発生したことを示すメッセージ。

コンフィギュレーション

<mdaConfig>
  <assistants>
    <streamWriterBufferedDataLost />
  </assistants>
</mdaConfig>

こちらも参照ください