служба Windows vs запланированное задание - PullRequest
106 голосов
/ 24 декабря 2008

В чем преимущества и недостатки служб Windows по сравнению с запланированными задачами для повторного запуска программы (например, каждые две минуты)?

Ответы [ 11 ]

47 голосов
/ 16 ноября 2009

Обновление:

Почти через четыре года после моего первоначального ответа, и этот ответ очень устарел. С появлением TopShelf разработка служб Windows стала легкой. Теперь вам просто нужно выяснить, как поддерживать аварийное переключение ...

Оригинальный ответ:

Я действительно не фанат Windows Scheduler. Пароль пользователя должен быть указан, как указано выше @ moodforall , что очень удобно, когда кто-то меняет пароль этого пользователя.

Другой большой недостаток планировщика Windows заключается в том, что он работает в интерактивном режиме, а не в качестве фонового процесса. Когда каждые 20 минут во время сеанса RDP появляются 15 окон MS-DOS, вы пинаете себя, что вместо этого не установили их как службы Windows.

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

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

После того, как вы написали все это, вы думаете, почему я просто не использовал Thread.Sleep? Это позволяет мне позволить текущему потоку продолжать работу до тех пор, пока он не завершится, а затем начинается интервал паузы, поток переходит в спящий режим и снова запускается через требуемое время. Ухоженная!

Затем вы читаете все советы в интернете, и многие эксперты рассказывают вам, насколько это действительно плохая практика программирования:

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

Так что вы почесаете голову и подумаете про себя, WTF, Отменить ожидающие проверки -> Да, я уверен -> Отменить всю сегодняшнюю работу ..... черт, черт, черт ....

Однако мне нравится этот шаблон, даже если все думают, что это дерьмо:

Метод OnStart для однопоточного подхода.

protected override void OnStart (string args) {

   // Create worker thread; this will invoke the WorkerFunction
   // when we start it.
   // Since we use a separate worker thread, the main service
   // thread will return quickly, telling Windows that service has started
   ThreadStart st = new ThreadStart(WorkerFunction);
   workerThread = new Thread(st);

   // set flag to indicate worker thread is active
   serviceStarted = true;

   // start the thread
   workerThread.Start();
}

Код создает отдельный поток и присоединяет нашего работника. функция к нему. Затем он запускает поток и запускает событие OnStart. завершено, так что Windows не думает, что служба зависла.

Рабочий метод для однопоточного подхода.

/// <summary>
/// This function will do all the work
/// Once it is done with its tasks, it will be suspended for some time;
/// it will continue to repeat this until the service is stopped
/// </summary>
private void WorkerFunction() {

   // start an endless loop; loop will abort only when "serviceStarted"
   // flag = false
   while (serviceStarted) {

      // do something
      // exception handling omitted here for simplicity
      EventLog.WriteEntry("Service working",
         System.Diagnostics.EventLogEntryType.Information);

      // yield
      if (serviceStarted) {
         Thread.Sleep(new TimeSpan(0, interval, 0));
      }
   }

   // time to end the thread
   Thread.CurrentThread.Abort();
}

Метод OnStop для однопоточного подхода.

protected override void OnStop() {

   // flag to tell the worker process to stop
   serviceStarted = false;

   // give it a little time to finish any pending work
   workerThread.Join(new TimeSpan(0,2,0));
}

Источник: http://tutorials.csharp -online.net / Создание_a_.NET_Windows_Service% E2% 80% 94Alternative_1% 3a_Use_a_Separate_Thread (Мертвая ссылка)

Я много лет запускал множество Windows Services, и это работает для меня. Я все еще не видел рекомендуемый образец, с которым люди соглашаются. Просто делай то, что тебе подходит.

15 голосов
/ 24 мая 2010

Некоторая дезинформация здесь. Планировщик Windows прекрасно способен выполнять задачи в фоновом режиме без всплывающих окон и без пароля. Запустите его под учетной записью NT AUTHORITY \ SYSTEM. Используйте этот переключатель schtasks:

/ ru СИСТЕМА

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

EDIT

В зависимости от вашей ОС и требований самой задачи вы можете использовать учетные записи с меньшими привилегиями, чем Localsystem, с опцией /ru.

Из штрафа Инструкция ,

/RU username

A value that specifies the user context under which the task runs. 
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM". 
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and 
"NT AUTHORITY\NETWORKSERVICE" are also valid values.

Task Scheduler 2.0 доступен в Vista и Server 2008.

В XP и Server 2003 system является единственным вариантом.

11 голосов
/ 24 декабря 2008

Каковы издержки запуска и выхода из приложения? Каждые две минуты довольно часто. Служба, вероятно, позволит системе работать более плавно, чем выполнение вашего приложения так часто.

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

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

10 голосов
/ 22 ноября 2011

При разработке .NET я обычно начинаю с разработки консольного приложения, которое будет запускать все записи журнала в окне консоли. Однако это только Консольное приложение, когда оно запускается с аргументом команды /console. Когда он запускается без этого параметра, он действует как служба Windows, которая будет работать в моем собственном кодированном таймере.

Службы Windows, по моему мнению, обычно используются для управления другими приложениями, а не как долго работающие приложения. ИЛИ ... это постоянно работающие тяжелые приложения, такие как SQL Server, BizTalk, RPC-соединения, IIS (даже если IIS технически разгружает работу для других процессов).

Лично я предпочитаю запланированные задачи, а не Windows Services, для выполнения задач и приложений для повторного обслуживания, таких как копирование / синхронизация файлов, массовая отправка электронной почты, удаление или архивирование файлов, исправление данных (когда другие обходные пути недоступны).

Для одного проекта я принимал участие в разработке 8 или 9 служб Windows, но они сидят в памяти, простаивают, потребляя 20 МБ или больше памяти на экземпляр. Запланированные задачи сделают свое дело и немедленно освободят память.

8 голосов
/ 01 августа 2013

Слово «serv'ice» имеет нечто общее с «serv'er». Ожидается, что он всегда будет запущен, и 'serv'e. Задача есть задача.

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

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

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

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

Хорошо, в заключение, это сильно зависит от многих факторов, но, надеюсь, это дало понимание, а не путаницу.

4 голосов
/ 24 декабря 2008
  1. Проще настроить и заблокировать службы Windows с правильными разрешениями.
  2. Сервисы более «видимы», что означает, что каждый (например, технический специалист) знает, где искать.
3 голосов
/ 24 декабря 2008

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

Запланированное задание не требует от вас обучения написанию службы Windows.

2 голосов
/ 24 июля 2016

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

Недавно мне было предложено сделать снимок экрана радара (с метеорологического веб-сайта) и сохранять его на сервере каждые 10 минут.

Это потребовало от меня использования WebBrowser. Я обычно делаю службы Windows, поэтому я решил сделать эту службу тоже, но она продолжит падать. Это то, что я видел в Event Viewer Неверный путь к модулю: C: \ Windows \ system32 \ MSHTML.dll

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

Мне очень понравилась статья Джона Галлоуэя , рекомендованная в принятом ответе Марком Рэнсомом.

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

Также упомянутая вещь, если вы используете всплывающие окна планировщика задач или окно консоли. Я никогда не сталкивался с этим. Это может всплыть, но, по крайней мере, очень мгновенно.

2 голосов
/ 24 декабря 2008

Почему бы не предоставить оба?

В прошлом я помещал «основные» биты в библиотеку и заключал в себе вызов Whwhat.GoGoGo () как в службе, так и в консольном приложении.

С чем-то, что вы запускаете каждые две минуты, шансы приличны, это не очень много (например, просто функция типа "ping"). Оболочки не должны содержать намного больше, чем один вызов метода и некоторое журналирование.

0 голосов
/ 18 марта 2019

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

В прошлом мы более или менее всегда использовали Windows Services, но также все больше и больше наших клиентов переходят на Azure шаг за шагом, и переход от консольного приложения (развернутого как запланированная задача) к WebJob в Azure значительно проще, чем из службы Windows, на данный момент мы сосредоточены на запланированных задачах. Если мы сталкиваемся с ограничениями, мы просто наращиваем проект службы Windows и вызываем ту же логику (пока клиенты работают с OnPrem ..):)

BR, у

...