streamWriterBufferedDataLost MDA

streamWriterBufferedDataLost Asystent zarządzanego debugowania (MDA) jest aktywowany, gdy StreamWriter element jest zapisywany, ale Flush metoda or Close nie jest następnie wywoływana przed zniszczeniem wystąpienia StreamWriter obiektu . Po włączeniu tego rozwiązania MDA środowisko uruchomieniowe określa, czy jakiekolwiek buforowane dane nadal istnieją w obiekcie StreamWriter. Jeśli dane buforowane istnieją, usługa MDA jest aktywowana. Collect Wywoływanie metod i WaitForPendingFinalizers może wymusić uruchamianie finalizatorów. Finalizatory w przeciwnym razie będą działać w pozornie arbitralnych czasach, a być może w ogóle nie po zakończeniu procesu. Jawne uruchamianie finalizatorów z włączoną funkcją MDA pomoże bardziej niezawodnie odtworzyć ten typ problemu.

Objawy

Element StreamWriter nie zapisuje danych w pliku z ostatnich 1–4 KB.

Przyczyna

Dane StreamWriter buforowane wewnętrznie, co wymaga Close wywołania metody lub Flush w celu zapisania buforowanych danych do bazowego magazynu danych. Jeśli Close lub Flush nie jest odpowiednio wywoływana, dane buforowane w wystąpieniu mogą nie być zapisywane zgodnie z StreamWriter oczekiwaniami.

Poniżej przedstawiono przykład źle napisanego kodu, który powinien przechwycić ten program MDA.

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

Powyższy kod aktywuje to rozwiązanie MDA bardziej niezawodnie, jeśli zostanie wyzwolone odzyskiwanie pamięci, a następnie wstrzymane do momentu zakończenia finalizatorów. Aby prześledzić ten typ problemu, możesz dodać następujący kod na końcu poprzedniej metody w kompilacji debugowania. Pomoże to w niezawodnym aktywowaniu mda, ale oczywiście nie rozwiąże przyczyny problemu.

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

Rozwiązanie

Przed zamknięciem aplikacji lub dowolnego bloku kodu, który ma wystąpienie StreamWriterobiektu , upewnij się, że wywołano Close metodę lub Flush na StreamWriter obiekcie . Jednym z najlepszych mechanizmów osiągnięcia tego celu jest utworzenie wystąpienia z blokiem języka C# using (Using w Visual Basic), co zapewni Dispose wywołanie metody modułu zapisywania, co spowoduje poprawne zamknięcie wystąpienia.

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

Poniższy kod przedstawia to samo rozwiązanie, przy użyciu polecenia try/finally zamiast using.

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

Jeśli nie można użyć żadnego z tych rozwiązań (na przykład jeśli element StreamWriter jest przechowywany w zmiennej statycznej i nie można łatwo uruchomić kodu po jego okresie istnienia), wywołanie Flush metody po StreamWriter jej ostatnim użyciu lub ustawienie AutoFlush właściwości na true wartość przed jej pierwszym użyciem powinno uniknąć tego problemu.

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

Wpływ na środowisko uruchomieniowe

To rozwiązanie MDA nie ma wpływu na środowisko uruchomieniowe.

Dane wyjściowe

Komunikat wskazujący, że to naruszenie miało miejsce.

Konfiguracja

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

Zobacz też