注
この記事は .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のインスタンスを含むコード ブロックを閉じる前に、StreamWriterでCloseまたは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>
こちらも参照ください
.NET