streamWriterBufferedDataLost MDA
Kommentar
Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.
Den streamWriterBufferedDataLost
hanterade felsökningsassistenten (MDA) aktiveras när en StreamWriter skrivs till, men Flush metoden eller Close anropas inte senare innan instansen StreamWriter av förstörs. När denna MDA är aktiverad avgör körningen om det fortfarande finns buffrade data i StreamWriter. Om buffrade data finns aktiveras MDA. Collect Att anropa metoderna och WaitForPendingFinalizers kan tvinga finalizers att köras. Finalizers kommer annars att köras vid till synes godtyckliga tidpunkter, och eventuellt inte alls vid processavslut. Om du uttryckligen kör finalizers med den här MDA-aktiverade funktionen kan du återskapa den här typen av problem på ett mer tillförlitligt sätt.
Symtom
A StreamWriter skriver inte de sista 1–4 KB-data till en fil.
Orsak
Buffrar StreamWriter data internt, vilket kräver att Close metoden eller Flush anropas för att skriva buffrade data till det underliggande datalagret. Om Close eller Flush inte anropas korrekt kanske data som buffrats i instansen StreamWriter inte skrivs som förväntat.
Följande är ett exempel på dåligt skriven kod som denna MDA bör fånga.
// Poorly written code.
void Write()
{
StreamWriter sw = new StreamWriter("file.txt");
sw.WriteLine("Data");
// Problem: forgot to close the StreamWriter.
}
Föregående kod aktiverar den här MDA:en mer tillförlitligt om en skräpinsamling utlöses och sedan pausas tills slutförarna har slutförts. Om du vill spåra den här typen av problem kan du lägga till följande kod i slutet av föregående metod i en felsökningsversion. Detta hjälper till att aktivera MDA på ett tillförlitligt sätt, men det löser naturligtvis inte orsaken till problemet.
GC.Collect();
GC.WaitForPendingFinalizers();
Åtgärd
Kontrollera att du anropar Close eller Flush på StreamWriter innan du stänger ett program eller något kodblock som har en instans av en StreamWriter. En av de bästa mekanismerna för att uppnå detta är att skapa instansen med ett C#- using
block (Using
i Visual Basic), vilket säkerställer Dispose att metoden för skrivaren anropas, vilket resulterar i att instansen stängs korrekt.
using(StreamWriter sw = new StreamWriter("file.txt"))
{
sw.WriteLine("Data");
}
Följande kod visar samma lösning med i try/finally
stället för using
.
StreamWriter sw;
try
{
sw = new StreamWriter("file.txt"));
sw.WriteLine("Data");
}
finally
{
if (sw != null)
sw.Close();
}
Om ingen av dessa lösningar kan användas (till exempel om en StreamWriter lagras i en statisk variabel och du inte enkelt kan köra kod i slutet av dess livslängd), bör du undvika det här problemet genom att anropa FlushStreamWriter efter den senaste användningen eller ställa in AutoFlush egenskapen på true
före den första användningen.
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;
}
Effekt på körningen
Denna MDA har ingen effekt på körningen.
Output
Ett meddelande som anger att den här överträdelsen inträffade.
Konfiguration
<mdaConfig>
<assistants>
<streamWriterBufferedDataLost />
</assistants>
</mdaConfig>