C # Windows Services + длительный рабочий процесс - PullRequest
1 голос
/ 10 августа 2010

Я начинаю разработку службы Windows и хотел бы проконсультироваться с разумом в работе над stackoverflow, прежде чем углубляться в него, чтобы узнать, как лучше всего с ним справиться.

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

Сервис будет иметь следующие функции на высоком уровне:

  • Отслеживание папки на наличие новых файлов (планирование использования FileSystemWatcher).
  • При обнаружении файла он ставится в очередь для загрузки на внешний хост.
  • Если в нем есть файлыОчередь, последовательно HTTP POST эти файлы на внешний хост.
    • Файлы должны быть POST'ы по одному (последовательно) и должны передаваться с использованием HTTP POST.
  • После успешного HTTP POST он удалитлокальный файл и, при необходимости, перейдите к следующему файлу в очереди загрузки и повторите процесс.

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

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

Заранее спасибо overflow'ers!

Ответы [ 7 ]

3 голосов
/ 10 августа 2010

Служба Windows не является плохой идеей IMO, особенно если вы хотите, чтобы она постоянно запускалась, пытаясь обнаружить запись файла в папку.Ограничение HTTP POST является значительным, но вы знаете, сколько времени и ресурсов он займет.Я думаю, что ваша самая большая проблема будет в очереди и управлении ресурсами.Вы захотите объединить каждый из этих переносов в процесс BackgroundWorker, чтобы несколько файлов могли быть завершены независимо, но вы также захотите иметь класс управления, который может ограничивать количество объектов BackgroundWorker, которые могут быть ускорены.В противном случае вы столкнетесь с проблемами управления памятью, сабжами в сети и, кто знает, что еще.

Вам следует учитывать наихудший / лучший сценарий появления файлов в папке.Какое наибольшее количество файлов может отображаться одновременно, какой размер файла может быть наибольшим, что происходит, когда папка начинает выполнять «резервное копирование», потому что HTTP POST не доставляет их к месту назначения достаточно быстро.Что происходит, когда хост назначения недоступен?Что происходит, когда система перезагружается «в середине поставки»?Есть ли источник для определения приоритета доставки файлов?Существуют ли ситуации, когда доставка файла должна быть прервана или реверсирована транзакцией?

Я думаю, что служба Windows - правильный выбор в сочетании с FileSystemWatcher.Просто следите за использованием вашего ресурса.

1 голос
/ 10 августа 2010

Служба Windows - определенно лучший способ. В вашем методе запуска службы вам нужно будет создать необходимые FileSystemWatcher экземпляры.

Когда создаются новые файлы, события будут запускаться, и вам придется своевременно обрабатывать эти события. Событие выполняется в потоке из пула потоков, и будущие события могут быть потеряны, если ваш обработчик событий не вернется немедленно. Это означает, что вам придется поставить в очередь какую-то задачу. Вы можете использовать новое в .NET 4 Task Parallel Library , a BackgroundWorker class, ThreadPool.QueueUserWorkItem method или что-то подобное. Как правило, все эти методы используют пул потоков .NET, размер которого ограничен, чтобы ограничить объем системных ресурсов, которые будет использовать ваша служба.

Постановка в очередь новой задачи каждый раз, когда создается новый файл, позволит задачам выполняться параллельно. Если вы хотите, чтобы одновременно выполнялась только одна задача, вам придется поместить задачи в очередь. Вы можете использовать энергозависимую очередь в памяти, но другой подход - использовать долговременную и транзакционную очередь MSMQ. Если файлы достаточно малы для хранения в очереди, вы можете прочитать, поставить в очередь и удалить файл транзакционным способом. Затем другая задача должна будет удалить файлы из очереди и обработать их. Любой сбой откатит транзакцию и сохранит файл в очереди. Это позволит обойти проблемы, связанные с попыткой использования файловой системы в качестве транзакционной базы данных.

Если ваши файлы поступают в быстром темпе, вам придется справиться с ситуацией, когда события из FileSystemWatcher пропускаются. Подход, при котором служба с регулярными интервалами (скажем, раз в минуту) сканирует файловую систему, может работать лучше для вас. Это можно сделать с помощью класса таймера (либо System.Timers.Timer class , либо System.Threading.Timer class ).

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

Если ваша служба должна быть очень надежной, вы должны учитывать все возможные сценарии сбоя, например, неожиданная остановка службы или переполнение диска.

0 голосов
/ 10 августа 2010

FileSystemWatcher

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

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

0 голосов
/ 10 августа 2010

Я согласен с остальными.Использование службы Windows для этой задачи имеет большой смысл.

Единственное руководство, которое я хотел бы получить, - избегать использования BackgroundWorker для многопоточности, поскольку вы делаете это внутри службы Windows.Класс BackgroundWorker предназначен для предоставления обратной связи о ходе вашей работы с потоками.Если вы не планируете иметь интерфейсное приложение, которое получает обратную связь от вашей службы Windows и затем представляет эту информацию пользователю (например, с помощью индикатора выполнения), объект BackgroundWorker является излишним для того, что вам нужно.Я бы предложил использовать классы ThreadPool или Thread в зависимости от конкретной ситуации.Некоторые указания относительно выбора см. В руководстве здесь .

0 голосов
/ 10 августа 2010

Недавно я использовал SmartThreadPool для управления одновременными загрузками FTP в приложении-службе Windows.

Служба Windows использует расписание Quartz.Net для запуска заданий загрузки по FTP, но мне нужно было выполнить 200 загрузок за короткий промежуток времени. Каждая отдельная загрузка занимала 15 минут, но все 200 необходимо было выполнить менее чем за 2 часа.

Когда Quartz запускал свои запланированные события, я заполнил SmartThreadPool 200 экземплярами класса, представляющими каждую конечную точку FTP, позволяя SmartThreadPool управлять использованием ресурсов. (у нас были проблемы с отсутствием триггеров Quartz, когда выполнение наших задач, выполняемых Quartz, занимало много времени, не больше минуты) *

Я обнаружил, что могу легко масштабировать до 60 потоков (самый высокий показатель), почти с линейным параллелизмом. То есть, когда для 200 последовательных загрузок потребуется почти ровно 50 часов, что позволяет SmartThreadPool использовать до 50 потоков, что сокращает весь процесс почти до 1 часа.

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

0 голосов
/ 10 августа 2010

Служба Windows - это путь.

Я не предвижу никаких проблем, так как раньше я делал почти то же самое, за исключением того, что я подключался к БД вместо службы http,и не было никаких проблем.

Вам не нужна многопоточность, тем более что вы размещаете каждый файл по одному.

Было бы полезно, если у вас есть приложение дляследите за своими услугами и отправляйте их по электронной почте / смс, когда они отключаются.

0 голосов
/ 10 августа 2010

Ну, если я вас правильно понимаю, то, что вы хотите достичь, не так уж сложно.

Я бы пошел за Windows-сервисом и FileSystemWatcher.нужно сделать.Единственное, что я хотел бы добавить - это загрузка файла, что легко сделать с помощью BackgroundWorker .За счет этого вы можете загружать несколько файлов асинхронно.

Дайте мне знать, если вам нужна дополнительная помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...