FileSystemWatcher.WaitForChanged возвращается, но файл все еще заблокирован

StackOverflow https://stackoverflow.com/questions/561467

Вопрос

У меня есть программа, которая отправляет документ в драйвер принтера PDF, и этот драйвер печатает в определенный каталог.После печати я хочу прикрепить PDF-файл к электронному письму (MailMessage) и отправить его.

Прямо сейчас я отправляю документ на принтер (который запускает новый процесс), а затем вызываю FileSystemWatcher.WaitForChanged(WaitForChangedResult.Created), но когда объект создается, его «печать» все еще не завершена, и принтер PDF все еще имеет блокирую его, выдавая ошибку, когда я пытаюсь прикрепить этот файл к электронному письму.

  • Я рассматривал простой Thread.Sleep(2000) или что-то еще, но это далеко не идеально.
  • Я подумывал о том, чтобы поместить код вложения в блок try/catch и зациклить его в случае неудачи, но опять же, это просто плохие новости.

Я не могу придумать элегантного решения.

Это было полезно?

Решение

WaitForChanges — это ожидание созданного события как у вас это закодировано.По мере создания документа вы получаете уведомление:это не означает, что файл полностью записан и блокировка снята.

К сожалению, я не знаю другого хорошего решения, кроме периодического опроса файла.Если бы было событие «все блокировки сняты», вы могли бы использовать его, но его нет.

Я только что проверил наш дамп PDF в коде каталога, и мы используем WaitForChanges только для обнаружения начала нового файла.Затем мы используем try {} catch {}, где catch (не получив права на файл) повторно отправляет попытку в поддерживаемую нами очередь:каждая попытка «отменяется» на более длительное время, поэтому первая попытка — через 1 секунду после обнаружения файла, вторая — через 2 секунды, затем 4, 8 и т. д.Это уменьшает количество повторных попыток обработки больших файлов, сохраняя при этом достаточную скорость реагирования на более короткие файлы.

Другие советы

Что ж, пока наблюдатель наблюдает за файлом и сообщает вам, когда он изменяется, вы можете просто игнорировать уведомления об изменениях, которые появляются, пока файлы все еще заблокированы (все еще записываются), и ждать окончательного уведомления об изменении, которое будет сигнализировать о последнее событие записи, после которого файл должен быть доступен (после чего вы можете наконец отключить часы).

Кроме этого, я не уверен, что вы можете сделать, потому что у наблюдателя нет события «закрытый файл» AFAIK.

AFAIK нет способа проверить блокировки файлов без обработки ошибок.

Может быть, принтер PDF запускается с новым процессом?Тогда вы сможете отслеживать этот процесс, и когда он завершится, ваш файл будет разблокирован.

Если вы используете для этого Adobe Acrobat, вы можете сгенерировать PDF-файл с помощью Acrodist.exe (мне сразу пришло в голову, вам нужен переключатель /N), а затем дождаться завершения порожденного процесса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top