Закройте/снова откройте TraceListener, созданный с конфигурацией XML, указывающий на внешний USB-накопитель.

У меня есть объект TraceListener, используемый для ведения журнала, созданный в app.config, который указывает на местоположение на USB-накопителе.

Я получаю IOException с сообщением

Объем файла был изменен извне, поэтому открытый файл больше недействителен.

при попытке Trace.WriteLine() после того, как я удалил устройство, а затем снова подключил его. Я понимаю, что это происходит, потому что дескриптор открытого файла, который есть у прослушивателя Trace, становится недействительным, когда я отключаю его.

Мне удалось помешать IOException, вызвав Close() в TraceListener, но я не могу понять, как снова открыть дескриптор того же файла. В документации MSDN для метода TextWriterTraceListener.Close() говорится

Вызов метода Write или WriteLine после вызова Close автоматически повторно открывает поток.

Но он просто не делает этого. Я не получаю дальнейший вывод после закрытия потока.

ИЗМЕНИТЬ:

Еще немного информации

Я обнаружил, что прослушиватель трассировки не может снова записать только в том случае, если после вызова Close() я попытаюсь записать, когда диск отключен от сети. Если я не пишу, когда диск отключен, снова подключите диск и попробуйте записать, все работает нормально. Я также проверил, что моя коллекция Trace.Listeners все еще содержит мой слушатель.


person Brandon    schedule 21.03.2014    source источник
comment
Глядя на внутренности TextWriterTraceListener, кажется, что внутренний метод EnsureWriter очищает имя файла, если создание потока завершается неудачно, и возвращает false, что делает метод строки записи недействительным. Последующие вызовы SureWriter сначала проверяют, пусто ли имя файла, и если да, то пропускают создание потока. Боюсь, вам придется создать собственный модуль записи, который более изящно обрабатывает удаление и повторное появление устройств.   -  person rene    schedule 23.03.2014
comment
Я боялся этого. Я нашел метод Trace.Refresh() в MSDN (msdn.microsoft.com/en-us/library/), который я успешно тестировал последние несколько часов. Я не уверен на 100%, что это то решение, которое мне нужно, но оно выглядит многообещающе.   -  person Brandon    schedule 24.03.2014
comment
Хммм, это в основном переинициализирует полную диагностическую структуру. Он очищает слушателей, источник трассировки и т. д. и воссоздает их, чтобы они работали...   -  person rene    schedule 24.03.2014
comment
Я не видел его исходный код, но знаю, что мы инициализируем только этот один прослушиватель в конфигурации приложения. Когда я читал об этом, мне он показался немного тяжелым. В любом случае я настаиваю на том, чтобы просто переписать эту структуру ведения журнала. Это было сделано далеко не должным образом. Я думаю, что обновление придется сделать сейчас   -  person Brandon    schedule 24.03.2014
comment
Сделайте свой текущий выход ответом. По крайней мере, я не считал это возможным. Если я смогу найти где-нибудь час, я соберу TraceListener, который обработает ваше дело...   -  person rene    schedule 24.03.2014


Ответы (1)


После множества исследований я обнаружил, что Trace.Refresh(), похоже, решает эту проблему, но, прочитав комментарии Рене к исходному вопросу, этот метод повторно инициализирует всю структуру Trace. Это кажется немного тяжелым для того, что я хотел, но, возможно, этот ответ поможет кому-то еще.

Trace.Refresh() в MSDN

Замечания из MSDN:

Данные конфигурации трассировки перехватываются при запуске приложения. Если данные конфигурации изменились после запуска приложения, вызовите метод Refresh, чтобы обновить данные конфигурации трассировки.

person Brandon    schedule 24.03.2014