Sdílet prostřednictvím


streamWriterBufferedDataLost – pomocník spravovaného ladění (MDA)

Poznámka:

Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.

Pomocník streamWriterBufferedDataLost spravovaného ladění (MDA) se aktivuje při zápisu StreamWriter do, ale Flush metoda nebo Close metoda není následně volána před zničením instance StreamWriter . Pokud je tato funkce MDA povolená, modul runtime určuje, zda v rámci tohoto StreamWritermodulu stále existují nějaká data uložená ve vyrovnávací paměti . Pokud data uložená do vyrovnávací paměti existují, aktivuje se MDA. Volání metod Collect a WaitForPendingFinalizers metod může vynutit spuštění finalizačních metod. Finalizační metody se jinak spustí v zdánlivě libovolných časech, a pravděpodobně ne vůbec při ukončení procesu. Explicitní spouštění finalizátorů s povoleným řešením MDA vám pomůže spolehlivěji reprodukovat tento typ problému.

Příznaky

A StreamWriter nezapisuje do souboru posledních 1–4 kB dat.

Příčina

Vyrovnávací StreamWriter paměť data interně, což vyžaduje, aby Close byla volána nebo Flush metoda k zápisu dat uložených do podkladového úložiště dat. Pokud Close nebo Flush není správně volána, data uložená do vyrovnávací paměti v StreamWriter instanci nemusí být zapsána podle očekávání.

Následuje příklad špatně napsaného kódu, který by tento MDA měl zachytit.

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

Předchozí kód aktivuje tuto mdA spolehlivěji, pokud se aktivuje uvolňování paměti a pak se pozastaví, dokud se nedokončí finalizační metody. Chcete-li zjistit tento typ problému, můžete do konce předchozí metody v sestavení ladění přidat následující kód. To pomůže spolehlivě aktivovat MDA, ale samozřejmě to neopraví příčinu problému.

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

Rozlišení

Close Před zavřením aplikace nebo FlushStreamWriter jakéhokoli bloku kódu, který má instanci objektu StreamWriter. Jedním z nejlepších mechanismů pro dosažení tohoto postupu je vytvoření instance s blokem jazyka C# using (Using v jazyce Visual Basic), který zajistí Dispose vyvolání metody pro zapisovač, což vede k správnému zavření instance.

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

Následující kód ukazuje stejné řešení, které používá místo try/finallyusing.

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

Pokud nelze použít žádná z těchto řešení (například pokud StreamWriter je uložena ve statické proměnné a nemůžete snadno spustit kód na konci jeho životnosti), pak by se mělo tomuto problému vyhnout volání FlushStreamWriter po posledním použití nebo nastavení AutoFlush vlastnosti true před jeho prvním použitím.

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

Vliv na modul runtime

Tento mdA nemá žádný vliv na modul runtime.

Výstup

Zpráva oznamující, že k tomuto porušení došlo.

Konfigurace

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

Viz také