Share via


streamWriterBufferedDataLost-MDA

Aktualisiert: November 2007

Der streamWriterBufferedDataLost-MDA (Managed Debugging Assistant, Assistent für verwaltetes Debuggen) wird aktiviert, wenn in einen StreamWriter geschrieben wird, jedoch anschließend kein Aufruf der Flush-Methode oder der Close-Methode erfolgt, bevor die Instanz von StreamWriter zerstört wird. Wenn dieser MDA bereitgestellt wurde, bestimmt die Laufzeit, ob im StreamWriter immer noch gepufferten Daten vorhanden sind. Wenn gepufferte Daten vorhanden sind, wird der MDA aktiviert. Durch Aufrufen der Collect-Methode und der WaitForPendingFinalizers-Methode kann das Ausführen von Finalizern erzwungen werden. Andernfalls werden Finalizer zu scheinbar beliebigen Zeiten und beim Prozessende möglicherweise gar nicht ausgeführt. Um diese Art von Problem zuverlässiger zu reproduzieren, ist es nützlich, Finalizer ausdrücklich aufzurufen und diesen MDA bereitzustellen.

Symptome

Ein StreamWriter schreibt die letzten 1-4 KB Daten nicht in eine Datei.

Ursache

Der StreamWriter puffert die Daten intern. Daher ist es erforderlich, die Close-Methode oder die Flush-Methode aufzurufen, damit die gepufferten Daten in den zugrunde liegenden Datenspeicher geschrieben werden. Wenn kein entsprechender Aufruf von Close oder Flush erfolgt, werden die in der StreamWriter-Instanz gepufferten Daten möglicherweise nicht erwartungsgemäß geschrieben.

Das folgende Beispiel stellt schlecht geschriebenen Code dar, der von diesem MDA abgefangen werden sollte.

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

Der Code im vorausgegangenen Beispiel aktiviert diesen MDA zuverlässiger, wenn eine Garbage Collection ausgelöst und dann unterbrochen wird, bis die Finalizer beendet wurden. Um dieser Art von Problem auf die Spur zu kommen, können Sie in einem Debugbuild den Code aus dem folgenden Beispiel an das Ende der Methode aus dem vorausgegangenen Beispiel anhängen. Dadurch wird der MDA zuverlässiger aktiviert (aber natürlich nicht die Ursache des Problems behoben).

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

Lösung

Stellen Sie sicher, dass ein Aufruf von Close oder Flush für den StreamWriter erfolgt, bevor die Anwendung bzw. jeder Codeblock geschlossen wird, in der bzw. dem eine Instanz eines StreamWriter verwendet wird. Am besten erreichen Sie dies, indem Sie die Instanz mit einem using-Block von C# erstellen (Using in Visual Basic). Dadurch wird sichergestellt, dass die Dispose-Methode für den Writer aufgerufen und die Instanz somit ordnungsgemäß geschlossen wird.

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

Im folgenden Codebeispiel wird dieselbe Lösung veranschaulicht, jedoch mit try/finally statt mit using.

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

Wenn keine dieser Lösungen verwendet werden kann, z. B. weil ein StreamWriter in einer statischen Variablen gespeichert ist und am Ende seiner Lebensdauer nicht einfach Code ausgeführt werden kann, rufen Sie nach dessen letzter Verwendung Flush für den StreamWriter auf, oder legen Sie vor dessen erster Verwendung die AutoFlush-Eigenschaft auf true fest, um dieses Problem zu vermeiden.

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;
}

Auswirkungen auf die Laufzeit

Dieser MDA hat keine Auswirkungen auf die Laufzeit.

Ausgabe

Eine Meldung, die angibt, dass diese Verletzung aufgetreten ist.

Konfiguration

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

Siehe auch

Konzepte

Diagnostizieren von Fehlern mit Assistenten für verwaltetes Debuggen

Referenz

StreamWriter