2010-11-03 2 views
2

Это немного запутанно, но я постараюсь объяснить как можно лучше.Ожидание события FileSystemWatcher перед завершением потока

Я использую FileSystemWatcher с уведомляют фильтром

toFileWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName; 

У меня есть метод .Created и метод .Changed.

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

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

что я хочу сделать, это закончить весь предварительный код, а затем я хочу, чтобы поток зависал до тех пор, пока не будет запущен метод .Changed для файла, указывающий, что файл сделан, так как я только улавливаю изменения в последний фильтр доступа.

ответ

1

Я бы установил отдельный поток, используя шаблон производителя-потребителя, который следит за тем, чтобы элементы отображались в очереди. Эти элементы будут представлять изменения файла и включать информацию, такую ​​как путь к файлу и какие изменения произошли. Ваши обработчики событий FileSystemWatcher просто отправляют элементы в очередь и позволяют потоку потребителя удалять и обрабатывать информацию. Это приведет к отмене требуемой обработки из событий уведомления файловой системы, где будет легче избежать проблем с «файлом в использовании».

+0

+1, согласовано. Но морщинка: это не типичная модель производителя-потребителя. Вы не можете потреблять до тех пор, пока операция не будет выполнена. –

+0

Да, определенно некоторые сложные детали будут разработаны ... –

2

Использование может использовать ManualResetEvent. Метод «Создать» может выполнить свою работу, а затем дождаться сигналов событий «Изменено», что способ «Создать» можно продолжить.

1

Эта проблема в норме, обычно вы не можете открыть файл, пока другой процесс занят записью на него. Вам нужно подождать, вы не можете предсказать, когда это будет сделано. Добавьте путь к файлу в список и используйте таймер для удаления этого списка, периодически повторяя операцию. Осторожно с логикой, вы используете потоки, поэтому вам нужно защитить список с помощью блокировки.

+0

Я действительно рассматривал модель с таймером, но я бы честно не использовал таймер или какой-либо цикл. Я знаю, что они эффективны, но я пытаюсь подтолкнуть свой стиль программирования к вызовам, управляемым событиями. – Patrick

+0

Ну, если бы вы знали достаточно о процессе, который записывает файл, вы, вероятно, не будете использовать FSW. –

+0

Сам процесс должен иметь возможность обрабатывать 20-30 различных файлов и размещать их в своих желаемых местах ... это также не специфичная для проекта функция. Это то, что есть и будет по-прежнему использоваться в нескольких разных проектах в компании. – Patrick

1

Обратите внимание, что NotifyFilters.LastAccess не означает, что вы будете знать, когда другой процесс завершится с файлом. Это просто означает, что вы получаете уведомление, когда последнее время доступа к файлу изменилось.

Обычно я использую образец производителя-потребителя Брайана Гидеона. Это также позволяет легко отфильтровать (типичные) несколько событий Changed, которые FileSystemWatcher счастливо раздаются.

Единственный способ быть уверенным, что другой процесс завершился с файлом, пытается получить на нем исключительную блокировку. Однако этого будет недостаточно. Я видел FTP-сервер, который закрывал и снова открывал файл для каждого записанного им блока ;-)

Также обратите внимание, что FileSystemWatcher имеет внутренний буфер, в котором он буферизует уведомления о файлах, которые он получает из Windows, но что этот буфер может переполняться, если произойдет много. Это опять же причина для создания потребителя-производителя.

Обычно я изменяю это, создавая процедуру, которая может вручную сканировать просмотренные каталоги, а затем запускать ее раз в то время.Да, опрос ;-)

Эта процедура также хороша при запуске приложения. Файлы, возможно, прибыли, пока он был вниз!

Смежные вопросы