2016-04-15 2 views
0

Я создал простую службу FileSystemWatcher, которая работает на моем компьютере:FileSystemWatcher алгоритм сортировки

public static void Run() 
    { 

     var watcher = new FileSystemWatcher 
     { 
      Path = @"C:\Users\XXX\Google Drive", 
      NotifyFilter = NotifyFilters.LastAccess 
          | NotifyFilters.LastWrite 
          | NotifyFilters.FileName 
          | NotifyFilters.DirectoryName, 

      Filter = "*.*", 
     }; 

     watcher.Created += OnChanged; 
     watcher.EnableRaisingEvents = true; 
    } 

    private static void OnChanged(object source, FileSystemEventArgs e) 
    { 
     FooPrintClass.SendToPrinter(e.FullPath); 
    } 

Как вы видите, я смотрю в папку Google Drive. Эта папка также синхронизируется на моем сервере. Время от времени система на моем сервере будет создать 2 пары файлов с тем же именем, но с diffrent типа:

(Foo.pdf, Foo.txt) 

Иногда система будет создавать более 50 из этих пар, и все они будут синхронизироваться с моим Google Дисковая папка.

Пока все хорошо, теперь к моей проблеме: Служба FileSystemWatcher работает так, как ожидалось, но не обрабатывает их ни в какой сортировке. Мне нужно мое обслуживание, чтобы фактически обрабатывать каждую пару за раз.

Expected Result: 
Foo.pdf, Foo.txt 
Bar.pdf, Foo.txt 

Actual Result: 
Bar.txt, Foo.pdf 
Foo.txt, Bar.pdf 

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

Любые советы?

+0

Место в массиве (или подходящей структуре данных), сортировка ....................... –

+0

FileSystemWatcher обрабатывает по одному файлу за раз. И как описано, я использую Google Диск. Это означает, что некоторые файлы могут быть синхронизированы перед другими. – Dandy

+0

id ожидает, что он отправит их вам, поскольку он их получит, так что это могут быть пара файлов, кэшируются и выполняются параллельно, и поэтому они не гарантируют порядок. – BugFinder

ответ

0

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

Для облегчения проблемы с синхронизацией вы можете синхронизировать файлы в связках. Если вы можете изменить систему, которая создает эти файлы, вы можете ZIP оба файла в одном zip-файле. Имея Foo.zip, вы можете распечатать оба файла по своему желанию.

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

+0

Можете ли вы подробнее рассказать о блокировке? Когда это может произойти? IFor теперь нет возможности для службы теперь о новых паре файлов. – Dandy

+0

Если одно приложение записывает или обновляет файл (Google Диск), вы можете получить уведомление от своего наблюдателя, но файл не закрыт в данный момент. Итак, если другое приложение (ваша служба) попытается открыть его, оно может получить сообщение об ошибке. Это сильно зависит от схемы, как первое приложение работает с файлами, условиями гонки. Проблема в том, что он может работать на вашем компьютере с таким же небольшим количеством файлов, но в реальных условиях вы можете столкнуться с проблемой. Кроме того, другое приложение может изменить способ работы с файлами в будущем, это может вызвать проблемы позже. –

+0

В целом это не надежный подход. По крайней мере, при реализации вашего алгоритма вы не должны полагаться на файлы, которые доступны немедленно, когда вы получаете уведомления и реализуете некоторый подход к повторной попытке. –

0

Вы можете использовать Reactive Extensions для буферизации ряда событий и сортировки их до продолжения.

Примером может быть что-то вроде этого:

Observable 
    .FromEventPattern<FileSystemEventArgs>(watcher, "Created") 
    .Buffer(TimeSpan.FromSeconds(10)) 
    .Subscribe(onNext); 

public void onNext(IList<string>) { ... } 

Пример буферами все изменения, происходящие в течение 10 секунд и передает их onNext в виде списка. Это позволяет вам сортировать файлы, прежде чем делать что-либо еще.

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

+0

Звучит неплохо, но если я добавлю 10 секунд для каждой пары файлов, это повлияет на отрицательную производительность – Dandy

+0

«Буфер» - это всего лишь один вариант. Вы можете сделать так, чтобы Rx ждал, пока не появится второй файл (независимо от порядка), а затем передайте оба файла функции.У меня нет сразу ответа на вопрос о том, как это сделать. Но вы можете посмотреть на решения, которые ждут конкретных комбинаций клавиш или чего-то подобного. – Chrono