Разрешение используемого файла исключений после закрытия StreamWriter
Я получаю ошибку:
The process cannot access the file
'C:\AMR_VOYANT_TESTING\PWM_TESTER\UUT_LOGS\TEST_LOG_PWM_10245_UUT_SN_10.TXT'
because it is being used by another process.
Моя программа сбрасывает, закрывает и удаляет файл журнала. Позже моя программа пытается открыть файл, чтобы добавить больше данных. Это второе открытие вызывает вышеуказанное исключение.
Process Explorer
не показывает дескриптор файла, во время выполнения либо прямой доступ к двоичному файлу, либо работа в режиме отладки с MS Visual C# Express 2008.
Никакие другие процессы не должны использовать этот файл, так как это оригинальный файл, созданный моим приложением.
Некоторые решения в Stack Overflow предлагают реализовать using
утверждение, но это неосуществимо, потому что запись данных не происходит в простой или короткой составной инструкции. Записывающий делегат используется классом ведения журнала для записи данных в файл.
Согласно другим решениям в Stack Overflow, в for
Цикл, файл не может быть закрыт до следующей итерации, где файл открывается. Я ждал более 10 секунд, прежде чем снова открыть файл, но безрезультатно (то же исключение).
Вот пример кода:
public void
close()
{
get_log_file().WriteLine("");
get_log_file().Flush();
get_log_file().Close();
get_log_file().Dispose();
m_log_file = null;
return;
}
private StreamWriter
get_log_file()
{
if (m_log_file == null)
{
bool successful = false;
int retries_remaining = 5;
// do
// {
// try
// {
// m_log_file = new StreamWriter(m_filename, true);
m_log_file = new StreamWriter(new FileStream(m_filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
// }
// catch (IOException)
// {
// --retries_remaining;
// System.Threading.Thread.Sleep(250); // Units are in milliseconds;
// }
// } while (!successful && (retries_remaining >= 0));
}
return m_log_file;
}
private System.IO.StreamWriter m_log_file = null;
private string m_filename;
Поскольку у меня есть крайний срок, я ищу решения по этому вопросу. Некоторые из моих идей:
- Держите файл открытым; не открывайте и не закрывайте во время тестовых прогонов.
- Показывать пользователю сообщение "в ожидании файла" во время опроса файла (чтобы увидеть, когда он может быть открыт снова)
- Написание неуправляемой библиотеки C или C++ для обработки файлового ввода-вывода (поскольку неуправляемые C и C++ не используют.NET Framework).
- Изучение того, как сказать.NET Framework поторопиться и закрыть файл.
Я использую MS Visual C# 2008 Express на Windows 7, 64-битная архитектура.
4 ответа
Я решил эту проблему, сохранив файл открытым, что устраняло необходимость повторного открытия его каждый раз.
Я надеюсь, что быстрое решение предложит вам заменить FileMode.OpenorCreate
с FileMode.Append
;
Как отмечают другие, существует множество других вариантов ведения журнала, но я считаю, что это может предложить вам быстрый путь вперед от того места, где вы стоите, вместо того, чтобы идти назад, чтобы двигаться вперед.
Мне кажется, что ваш код - это фрагмент класса, который возвращает потоковый обработчик в вызывающий контекст. Я хотел бы, чтобы ваш класс реализовал IDisposable, изменив значение close на Dispose (чтобы реализовать IDisposable), а затем заставил бы вашего потребителя превратить вызов в использование (yourLogClass logger = new yourLogClass())... и т. Д., Чтобы гарантировать, что закрытие вызывается с каждым использованием.
Код, который вызывает методы в этом классе, не вызывает ваш метод close() после вызова метода open. Основываясь на опубликованном вами коде, я предполагаю, что существует отдельный метод open. Если этот метод вызывается более одного раза, вы получите исключение, которое вы описываете. Код, который вы опубликовали, не имеет проблем, которые могут вызвать исключение, которое вы получаете. Если вы вызываете Flush() перед вызовом Close(), это приведет к принудительной записи на диск, чтобы при вызове Close() не было задержки, я забивал файлы, открывая и закрывая их сотни раз за секунду или две, и никогда была эта проблема.
Обновление: если ваш код выдал исключение во время отладки, VS все еще имеет открытый дескриптор этого файла. Это продолжит генерировать это исключение, даже если вы исправили свой код. Я обычно просто закрываю и перезагружаю VS, чтобы не связываться с настройками моего проекта и случайно включить их в систему контроля версий.
- Если вы хотите сделать это правильно, вам придется потратить некоторое время. Или же
- Используйте систему трассировки или ведения журнала.
- Я предполагаю, что вы отлаживаете процесс размещения Visual Studio. Попробуйте отключить его и проверьте, исчезла ли проблема с блокировкой файлов.
Отключить флажок
Project - Properties - Debug - x Enable Visual Studio hosting process
Возможно также, что вы выполняете трассировку в одном из ваших финализаторов во время завершения работы приложения, когда StreaWriter уже был закрыт. Вы можете обойти это с помощью критического финализатора
С уважением, Алоис Краус