BinaryReader или Writer.Close() не закрывается должным образом C#
У меня есть приложение формы, которое выполняет симуляцию и постоянно читает / записывает двоичный файл. Все работает нормально, если вы позволите ему пройти. Однако, если форма закрыта / симуляция прервана, поток файлов не будет закрыт должным образом - файл останется заблокированным. Есть ли способ убедиться, что все потоки закрыты? Я попробовал следующее - но это не имеет никакого эффекта... Заранее большое спасибо, T
public BinaryWriter BinWrite;
public BinaryReader BinRead;
public BinaryWriter EnvBinWrite;
public BinaryReader EnvBinRead;
public void theForm_FormClosing(object sender, FormClosingEventArgs e)
{
//Close all binary file reader/writers -- crashes if it cannot overwrite files
foreach (Building B in AllBldgs)
{
try
{
EnvBinRead.Close();
}
catch
{ continue; }
try
{
EnvBinWrite.Close();
}
catch
{ continue; }
try
{
BinRead.Close();
}
catch
{ continue; }
try
{
BinWrite.Close();
}
catch
{ continue; }
}
}
3 ответа
Вы уверены, что знаете, что continue
ключевое слово для? Обратите внимание, что это продолжается со следующего цикла, а не со следующим блоком кода. Так что, если исключение происходит закрытие EnvBinRead
, вы не войдете в блок, чтобы закрыть EnvBinWrite
, но переходите к следующему пункту из AllBldgs
,
Чтобы съесть все исключения и все же попытаться закрыть все двоичные записи, вы должны написать:
foreach (Building B in AllBldgs)
{
try
{
EnvBinRead.Close();
}
catch (Exception exp)
{
Console.WriteLine("Closing EnvBinRead failed!" + exp.ToString());
}
try
{
EnvBinWrite.Close();
}
catch (Exception exp)
{
Console.WriteLine("Closing EnvBinWrite failed!" + exp.ToString());
}
try
{
BinRead.Close();
}
catch (Exception exp)
{
Console.WriteLine("Closing BinRead failed!" + exp.ToString());
}
try
{
BinWrite.Close();
}
catch (Exception exp)
{
Console.WriteLine("Closing BinWrite failed!" + exp.ToString());
}
}
Обратите внимание, что употребление исключений никогда не является хорошей идеей. Если вам все равно, можно ли закрыть программу чтения или записи, проверьте, была ли она инициализирована, прежде чем закрывать ее, как это предлагается в комментариях.
Вы должны вызвать dispose, чтобы закрыть BinaryReader и Writer.
Объяснение:
StreamReader, StreamWriter, BinaryReader and BinaryWriter
все закрывают / удаляют свои базовые потоки, когда вы вызываете Dispose для них. Они не утилизируют поток, если читатель / писатель просто собирает мусор - вы всегда должны утилизировать читателя / писателя, желательно с using
заявление. (На самом деле, ни у одного из этих классов нет финализаторов, и при этом они не должны быть.)
Лично я предпочитаю иметь оператор использования для потока. Вы можете аккуратно вложить операторы без скобок:
using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}
Хотя using
оператор для потока несколько избыточен (если только StreamReader
конструктор выдает исключение) Я считаю, что это лучшая практика, как если бы вы избавились от StreamReader
и просто используйте поток непосредственно позднее, у вас уже будет правильная семантика удаления.
Всегда полезно использовать блок Блок для потоков, закрывая их сразу после использования.