streamWriterBufferedDataLost MDA

更新 : 2007 年 11 月

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

症状

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

原因

StreamWriter はデータを内部にバッファリングします。この場合、Close メソッドまたは Flush メソッドを呼び出して、バッファ データを基になるデータ ストアに書き込む必要があります。CloseFlush が適切に呼び出されなかった場合、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();

解決策

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 が静的変数に格納され、その有効期間の最後にコードを簡単に実行できない場合など)、StreamWriter を最後に使用した後に Flush を呼び出すか、または最初に使用する前に 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>

参照

概念

マネージ デバッグ アシスタントによるエラーの診断

参照

StreamWriter