Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
Эта статья относится к .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>