Bagikan melalui


streamWriterBufferedDataLost MDA

Catatan

Artikel ini khusus untuk .NET Framework. Ini tidak berlaku untuk implementasi .NET yang lebih baru, termasuk .NET 6 dan versi yang lebih baru.

streamWriterBufferedDataLost Asisten Penelusuran Kesalahan Terkelola (MDA) diaktifkan saat StreamWriter ditulis, tetapi metode Flush atau Close tidak dipanggil setelah itu sebelum instans StreamWriter dimusnahkan. Saat MDA ini diaktifkan, runtime menentukan apakah data yang di-buffer masih ada dalam StreamWriter. Jika data buffer memang ada, MDA diaktifkan. Memanggil metode Collect dan WaitForPendingFinalizers dapat memaksa pengakhir untuk berjalan. Pengakhir sebaliknya akan berjalan pada waktu yang tampaknya sewenang-wenang, dan mungkin tidak sama sekali pada proses keluar. Menjalankan pengakhir secara eksplisit dengan MDA yang diaktifkan ini akan membantu mereproduksi jenis masalah ini dengan lebih andal.

Gejala

StreamWriter tidak menulis 1-4 KB data terakhir ke file.

Penyebab

StreamWriter buffer data secara internal, yang mengharuskan metode Close atau Flush dipanggil untuk menulis data buffer ke penyimpanan data yang mendasarinya. Jika Close atau Flush tidak dipanggil dengan tepat, data yang di-buffer dalam instans StreamWriter mungkin tidak ditulis seperti yang diharapkan.

Berikut ini adalah contoh kode yang ditulis dengan buruk yang harus ditangkap oleh MDA ini.

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

Kode sebelumnya akan mengaktifkan MDA ini dengan lebih andal jika pengumpulan sampah dipicu dan kemudian ditangguhkan hingga pengakhir selesai. Untuk melacak jenis masalah ini, Anda dapat menambahkan kode berikut ke akhir metode sebelumnya dalam build debug. Cara ini akan membantu mengaktifkan MDA dengan andal, tetapi tentu saja itu tidak memperbaiki penyebab masalah.

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

Resolusi

Pastikan Anda memanggil Close atau Flush pada StreamWriter sebelum menutup aplikasi atau blok kode apa pun yang memiliki turunan StreamWriter. Salah satu mekanisme terbaik untuk mencapai ini adalah membuat instans dengan blok C# using (Using dalam Visual Basic), yang akan memastikan metode Dispose untuk penulis dipanggil, sehingga instans ditutup dengan benar.

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

Kode berikut menunjukkan solusi yang sama, menggunakan try/finally sebagai ganti using.

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

Jika tidak satu pun dari solusi ini dapat digunakan (misalnya, jika StreamWriter disimpan dalam variabel statis dan Anda tidak dapat dengan mudah menjalankan kode di akhir masa pakainya), maka panggil Flush pada StreamWriter setelah yang terakhir menggunakan atau mengatur properti AutoFlush ke true sebelum penggunaan pertama akan menghindari masalah ini.

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

Efek pada Runtime

MDA ini tidak berpengaruh pada runtime.

Output

Pesan yang menunjukkan bahwa pelanggaran ini terjadi.

Konfigurasi

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

Lihat juga