MDA streamWriterBufferedDataLost
Aggiornamento: novembre 2007
L'assistente al debug gestito streamWriterBufferedDataLost viene attivato quando si scrive in un oggetto StreamWriter senza che venga successivamente chiamato il metodo Flush o Close prima dell'eliminazione dell'istanza di StreamWriter. Se questo assistente al debug gestito è abilitato, Common Language Runtime determina se sono ancora presenti dati nel buffer di StreamWriter. In caso affermativo, l'assistente al debug gestito viene attivato. La chiamata ai metodi Collect e WaitForPendingFinalizers può imporre l'esecuzione dei finalizzatori. In caso contrario, i finalizzatori verranno eseguiti in momenti apparentemente arbitrari ed è anche possibile che non vengano eseguiti affatto alla chiusura di un processo. L'esecuzione esplicita dei finalizzatori mediante questo assistente al debug gestito consentirà di riprodurre in modo più affidabile questo tipo di problema.
Sintomi
Un oggetto StreamWriter non scrive gli ultimi 1-4 KB di dati in un file.
Causa
StreamWriter memorizza i dati nel buffer interno, richiedendo quindi la chiamata al metodo Close o Flush per la scrittura dei dati del buffer nell'archivio dati sottostante. Se il metodo Close o Flush non viene chiamato in modo appropriato, è possibile che i dati contenuti nel buffer dell'istanza di StreamWriter non vengano scritti nel modo previsto.
Di seguito è riportato un esempio di codice non corretto che dovrebbe essere rilevato 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 la Garbage Collection viene avviata e quindi sospesa finché non termina l'esecuzione dei finalizzatori. Per individuare questo tipo di problema, è possibile aggiungere il codice riportato di seguito alla fine del metodo precedente in una build di debug. In questo modo l'assistente al debug gestito verrà attivato correttamente, ma non verrà ovviamente corretta la causa del problema.
GC.Collect();
GC.WaitForPendingFinalizers();
Soluzione
Prima di chiudere un'applicazione o un blocco di codice contenente un'istanza di StreamWriter, assicurarsi di chiamare Close o Flush sull'oggetto StreamWriter. Una delle migliori soluzioni consiste nel creare l'istanza con un blocco using di C# (Using in Visual Basic), in modo da assicurare la chiamata al metodo Dispose per il writer e quindi la chiusura corretta dell'istanza.
using(StreamWriter sw = new StreamWriter("file.txt"))
{
sw.WriteLine("Data");
}
Nel codice riportato di seguito viene illustrata la stessa soluzione, in questo caso utilizzando try/finally anziché using.
StreamWriter sw;
try
{
sw = new StreamWriter("file.txt"));
sw.WriteLine("Data");
}
finally
{
if (sw != null)
sw.Close();
}
Se queste soluzioni non possono essere utilizzate, ad esempio quando un oggetto StreamWriter è memorizzato in una variabile statica e non è possibile eseguire facilmente il codice alla fine della durata della variabile, per evitare questo problema è possibile chiamare il metodo Flush sull'oggetto StreamWriter dopo l'ultimo utilizzo oppure impostare la proprietà AutoFlush su true prima del primo utilizzo.
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;
}
Effetti su Common Language Runtime
Questo assistente al debug gestito non ha alcun effetto su Common Language Runtime (CLR).
Output
Un messaggio indicante che si è verificata questa violazione.
Configurazione
<mdaConfig>
<assistants>
<streamWriterBufferedDataLost />
</assistants>
</mdaConfig>
Vedere anche
Concetti
Diagnostica degli errori tramite gli assistenti al debug gestito