Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Замечание
Эта статья относится к .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>