Бөлісу құралы:


streamWriterBufferedDataLost MDA

Замечание

Эта статья относится к .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.

Помощник streamWriterBufferedDataLost по управляемой отладке (MDA) активируется при StreamWriter записи в, но FlushClose метод или метод впоследствии не вызывается перед уничтожением экземпляра StreamWriter . Если этот MDA включен, среда выполнения определяет, существуют ли буферные данные в пределах.StreamWriter Если буферные данные существуют, MDA активируется. Collect Вызов методов и WaitForPendingFinalizers методов может принудительно запускать методы завершения. В противном случае методы завершения будут работать в произвольное время, и, возможно, не вообще при выходе процесса. Явным образом запущенные средства завершения с включенным MDA помогут более надежно воспроизвести этот тип проблемы.

Симптомы

Не StreamWriter записывает последние 1–4 КБ данных в файл.

Причина

Буферы StreamWriter внутренние данные, требующие Close вызова или Flush метода для записи буферных данных в базовое хранилище данных. Flush Если Close или нет соответствующего вызова, данные, буферизированные в экземпляреStreamWriter, могут не записываться должным образом.

Ниже приведен пример плохо написанного кода, который должен перехватывать этот MDA.

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

Предыдущий код активирует этот MDA более надежно, если сборка мусора активируется, а затем приостановлена до завершения завершения. Чтобы отслеживать этот тип проблемы, можно добавить следующий код в конец предыдущего метода в отладочной сборке. Это поможет надежно активировать MDA, но, конечно, это не исправляет причину проблемы.

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

Резолюция

Перед Close закрытием приложения или FlushStreamWriter любого блока кода, имеющего экземпляр a.StreamWriter Одним из лучших механизмов для достижения этого является создание экземпляра с блоком C# using (Using в Visual Basic), что обеспечит Dispose вызов метода записи, что приведет к правильному закрытию экземпляра.

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

В следующем коде показано то же решение, которое используется try/finally вместо using.

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

Если ни из этих решений не может использоваться (например, если StreamWriter хранящийся в статической переменной и вы не сможете легко запустить код в конце его существования), вызовите FlushStreamWriter свойство после последнего использования или присвойте AutoFlush свойству значение true до его первого использования, следует избежать этой проблемы.

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

Влияние на среду выполнения

Этот MDA не влияет на среду выполнения.

Выходные данные

Сообщение, указывающее, что это нарушение произошло.

Конфигурация

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

См. также