Condividi tramite


streamWriterBufferedDataLost MDA

Annotazioni

Questo articolo è specifico per .NET Framework. Non si applica alle implementazioni più recenti di .NET, tra cui .NET 6 e versioni successive.

L'assistente streamWriterBufferedDataLost al debug gestito viene attivato quando un StreamWriter oggetto viene scritto in , ma il Flush metodo o Close non viene chiamato successivamente prima che l'istanza StreamWriter di venga eliminata definitivamente. Quando questo assistente al debug gestito è abilitato, il runtime determina se tutti i dati memorizzati nel buffer sono ancora presenti all'interno di StreamWriter. Se esistono dati memorizzati nel buffer, l'assistente al debug gestito viene attivato. La chiamata ai metodi e WaitForPendingFinalizers può forzare l'esecuzione Collect dei finalizzatori. I finalizzatori verranno altrimenti eseguiti in momenti apparentemente arbitrari e probabilmente non affatto all'uscita del processo. L'esecuzione esplicita dei finalizzatori con questo assistente al debug gestito abilitato consente di riprodurre in modo più affidabile questo tipo di problema.

Symptoms

Un StreamWriter oggetto non scrive gli ultimi 1-4 KB di dati in un file.

Motivo

I StreamWriter dati memorizzati nel buffer internamente, che richiedono che il Close metodo o Flush venga chiamato per scrivere i dati memorizzati nel buffer nell'archivio dati sottostante. Se Close o Flush non viene chiamato in modo appropriato, i dati memorizzati nel buffer nell'istanza StreamWriter potrebbero non essere scritti come previsto.

Di seguito è riportato un esempio di codice scritto in modo non corretto che questo assistente al debug gestito deve intercettare.

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

Il codice precedente attiverà questo assistente al debug gestito in modo più affidabile se viene attivata un'operazione di Garbage Collection e quindi sospesa fino al termine dei finalizzatori. Per tenere traccia di questo tipo di problema, è possibile aggiungere il codice seguente alla fine del metodo precedente in una compilazione di debug. Ciò consentirà di attivare in modo affidabile l'assistente al debug gestito, ma naturalmente non risolve la causa del problema.

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

Resolution

Assicurarsi di chiamare Close o Flush su prima di StreamWriter chiudere un'applicazione o qualsiasi blocco di codice con un'istanza di .StreamWriter Uno dei meccanismi migliori per ottenere questo risultato è la creazione dell'istanza con un blocco C# using (Using in Visual Basic), che garantisce che il Dispose metodo per il writer venga richiamato, causando la corretta chiusura dell'istanza.

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

Il codice seguente illustra la stessa soluzione, usando try/finally invece di using.

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

Se nessuna di queste soluzioni può essere usata (ad esempio, se un StreamWriter oggetto viene archiviato in una variabile statica e non è possibile eseguire facilmente il codice alla fine della durata), chiamare Flush dopo l'ultimo StreamWriter utilizzo o impostare la AutoFlush proprietà su true prima del primo utilizzo dovrebbe evitare questo problema.

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

Effetto sul runtime

Questo assistente al debug gestito non ha alcun effetto sul runtime.

Risultato

Messaggio che indica che si è verificata questa violazione.

Configurazione

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

Vedere anche