streamWriterBufferedDataLost (MDA)
Nota
Questo articolo è specifico per .NET Framework. Non si applica alle implementazioni più recenti di .NET, incluse .NET 6 e versioni successive.
L'assistente al debug gestito streamWriterBufferedDataLost
viene attivato quando viene scritto un StreamWriter, ma il metodo Flush o Close non viene chiamato in seguito prima dell'eliminazione definitiva dell'istanza di StreamWriter. Quando questo assistente al debug gestito è abilitato, il runtime determina se tutti i dati memorizzati nel buffer esistono ancora in StreamWriter. In caso affermativo, l'assistente al debug gestito viene attivato. La chiamata dei metodi Collect e WaitForPendingFinalizers può forzare l'esecuzione dei finalizzatori. In caso contrario, i finalizzatori vengono eseguiti in momenti apparentemente arbitrari e probabilmente non vengono eseguiti affatto all'uscita dal processo. L'esecuzione dei finalizzatori in modo esplicito con questo assistente al debug gestito sarà utile per riprodurre in modo più affidabile questo tipo di problema.
Sintomi
Un StreamWriter non scrive gli ultimi 1-4 KB di dati in un file.
Causa
StreamWriter memorizza nel buffer i dati internamente e ciò richiede che il metodo Close o Flush venga chiamato per scrivere i dati memorizzati nel buffer nell'archivio dati sottostante. Se il metodo Close o Flush non viene chiamato in modo appropriato, i dati memorizzati nel buffer nell'istanza di StreamWriter potrebbero non essere scritti come previsto.
Di seguito è riportato un esempio di codice non corretto che dovrebbe essere intercettato da questo assistente al debug gestito.
// 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 e poi sospesa un'operazione di Garbage Collection fino al completamento dei finalizzatori. Per analizzare questo tipo di problema, è possibile aggiungere il codice seguente alla fine del metodo precedente in una build di debug. Ciò sarà utile per attivare in modo affidabile l'assistente al debug gestito, ma ovviamente non risolve la causa del problema.
GC.Collect();
GC.WaitForPendingFinalizers();
Risoluzione
Assicurarsi di chiamare Close o Flush sul StreamWriter prima di chiudere un'applicazione o qualsiasi blocco di codice che ha un'istanza di un StreamWriter. Uno dei meccanismi migliori per ottenere questo risultato consiste nel creare l'istanza con un blocco using
C# (Using
in Visual Basic), che garantisce la chiamata del metodo Dispose per il writer, con conseguente chiusura corretta dell'istanza.
using(StreamWriter sw = new StreamWriter("file.txt"))
{
sw.WriteLine("Data");
}
Il codice seguente mostra la stessa soluzione, con 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 viene archiviato in una variabile statica e non è possibile eseguire facilmente il codice alla fine della durata), la chiamata di Flush su StreamWriter dopo l'ultimo uso oppure l'impostazione della proprietà AutoFlush su true
prima del primo uso dovrebbe consentire di 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 sull'ambiente di esecuzione
L'assistente al debug gestito non ha alcun effetto sull'ambiente di esecuzione.
Output
Un messaggio che indica che si è verificata questa violazione.
Impostazione
<mdaConfig>
<assistants>
<streamWriterBufferedDataLost />
</assistants>
</mdaConfig>