Ответы:
Обновить:
Спустя почти четыре года после моего первоначального ответа, этот ответ очень устарел. С появлением TopShelf разработка служб Windows упростилась. Теперь вам просто нужно выяснить, как поддерживать отказоустойчивость ...
Оригинальный ответ:
Я действительно не поклонник Windows Scheduler. Пароль пользователя должен быть предоставлен, как указывает @moodforall выше, что забавно, когда кто-то меняет пароль этого пользователя.
Еще одно серьезное раздражение Планировщика Windows заключается в том, что он работает в интерактивном режиме, а не в фоновом режиме. Когда 15 окон MS-DOS появляются каждые 20 минут во время сеанса RDP, вы пинаете себя за то, что не установили их как службы Windows.
Что бы вы ни выбрали, я определенно рекомендую вам выделить код обработки в другой компонент из консольного приложения или службы Windows. Затем у вас есть выбор: либо вызвать рабочий процесс из консольного приложения и подключить его к планировщику Windows, либо использовать службу Windows.
Вы обнаружите, что планирование службы Windows - это не весело. Довольно распространенный сценарий - у вас есть длительный процесс, который вы хотите запускать периодически. Но если вы обрабатываете очередь, вам действительно не нужно, чтобы два экземпляра одного и того же рабочего процесса обрабатывали одну и ту же очередь. Таким образом, вам нужно управлять таймером, чтобы убедиться, что если ваш длительный процесс работает дольше назначенного интервала таймера, он не запускается снова, пока существующий процесс не завершится.
После того, как вы все это написали, вы думаете, почему я просто не использовал Thread.Sleep? Это позволяет мне позволить текущему потоку продолжать работать до тех пор, пока он не завершится, а затем наступит интервал паузы, поток перейдет в спящий режим и снова запустится через требуемое время. Ухоженная!
Затем вы читаете все советы в Интернете, где множество экспертов рассказывают вам, как это действительно плохая практика программирования:
Так что вы почесаете затылок и подумаете про себя, WTF, Undo Pending Checkouts -> Да, я уверен -> Отменить всю сегодняшнюю работу ..... черт, черт, черт ....
Однако мне нравится этот паттерн, даже если все думают, что это чушь:
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/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (мертвая ссылка)
Я уже много лет использую множество подобных служб Windows, и мне это помогает. Я до сих пор не видел рекомендованного шаблона, с которым люди согласны. Просто делайте то, что работает для вас.
NT AUTHORITY\NetworkService
- это учетная запись с ограниченными привилегиями.
Некоторая дезинформация здесь. Планировщик Windows отлично способен выполнять задачи в фоновом режиме без всплывающих окон и без пароля. Запустите его под учетной записью NT AUTHORITY \ SYSTEM. Используйте этот переключатель schtasks:
/ ru СИСТЕМА
Но да, для доступа к сетевым ресурсам лучше всего использовать учетную запись службы с отдельной политикой паролей с неограниченным сроком действия.
РЕДАКТИРОВАТЬ
В зависимости от вашей ОС и требований самой задачи вы можете использовать учетные записи с меньшими привилегиями, чем 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.
Планировщик заданий 2.0 доступен в Vista и Server 2008.
В XP и Server 2003 system
это единственный вариант.
Local Service
(иначе NT AUTHORITY\LocalService
), а не как LocalSystem
(иначе .\LocalSystem
). Первый имеет ограниченные права, а второй является администратором
LocalService
и NetworkService
доступны в schtasks
v2 Vista , начиная и должно быть предпочтительным , где это возможно. В то время это относилось к schtasks
XP и Server 2003, которые принимают только в System
качестве параметра в соответствии с руководством по старой версии technet.microsoft.com/en-us/library/bb490996.aspx
Каковы накладные расходы при запуске и выходе из приложения? Каждые две минуты довольно часто. Служба, вероятно, позволила бы системе работать более плавно, чем столь частое выполнение вашего приложения.
Оба решения могут запускать программу, когда пользователь не вошел в систему, поэтому никакой разницы в этом нет. Однако написание службы несколько сложнее, чем обычное настольное приложение - вам может понадобиться отдельный клиент с графическим интерфейсом, который будет связываться с приложением службы через TCP / IP, именованные каналы и т. Д.
С точки зрения пользователя, интересно, что легче контролировать. И службы, и запланированные задачи в значительной степени недоступны для большинства нетехнических пользователей, то есть они даже не осознают, что существуют, и могут быть настроены / остановлены / перепланированы и так далее.
В разработке .NET я обычно начинаю с разработки консольного приложения, которое будет запускать все данные журнала, выводимые в окно консоли. Однако это только консольное приложение, когда оно запускается с аргументом команды /console
. Когда он запускается без этого параметра, он действует как служба Windows, которая будет продолжать работать в соответствии с моим собственным расписанным таймером.
На мой взгляд, службы Windows обычно используются для управления другими приложениями, а не для длительной работы. ИЛИ ... они являются постоянно работающими тяжеловесными приложениями, такими как SQL Server, BizTalk, RPC Connections, IIS (даже несмотря на то, что IIS технически переносит работу на другие процессы).
Лично я предпочитаю запланированные задачи службам Windows для повторяющихся задач обслуживания и приложений, таких как копирование / синхронизация файлов, массовая отправка электронной почты, удаление или архивирование файлов, исправление данных (когда другие обходные пути недоступны).
В одном проекте я участвовал в разработке 8 или 9 служб Windows, но они сидят в памяти, простаивают, потребляя 20 МБ или более памяти на каждый экземпляр. Запланированные задачи сделают свое дело и немедленно освободят память.
Слово «сервис» имеет нечто общее со словом «сервис». Ожидается, что он всегда будет запущен и 'serv'e. Задача есть задача.
Ролевая игра. Если я другая операционная система, приложение или устройство и вызываю службу, я ожидаю, что она будет запущена, и ожидаю ответа. Если мне (os, app, dev) просто нужно выполнить изолированную задачу, я выполню задачу, но если я ожидаю общения, возможно, двусторонней связи, мне нужна услуга. Это связано с наиболее эффективным способом взаимодействия двух объектов или одного объекта, который хочет выполнить одну задачу.
Тогда есть аспект планирования. Если вы хотите, чтобы что-то запускалось в определенное время, запланируйте. Если вы не знаете, когда он вам понадобится, или он вам понадобится «на лету», сервис.
Мой ответ носит более философский характер, потому что это очень похоже на то, как люди взаимодействуют и работают с другими. Чем больше мы понимаем искусство общения, а «сущности» понимают свою роль, тем легче становится принятие этого решения.
Если оставить в стороне всю философию, когда вы «быстро создаете прототип», как это часто делает мой ИТ-отдел, вы делаете все возможное, чтобы свести концы с концами. После того, как прототипирование и проверка концепции закончились, обычно на раннем этапе планирования и обнаружения, вы должны решить, что более надежно для долгосрочной устойчивости.
Хорошо, в заключение, это сильно зависит от множества факторов, но, надеюсь, это дало понимание, а не путаницу.
Служба Windows не требует, чтобы кто-либо вошел в систему, и в Windows есть средства для остановки, запуска и регистрации результатов службы.
Запланированная задача не требует от вас обучения написанию службы Windows.
NT AUTHORITY\LocalService
, или NT AUTHORITY\NetworkService
). Любой предоставленный пароль игнорируется, поскольку у учетных записей нет пароля.
Почему бы не предоставить и то, и другое?
Раньше я помещал «основные» биты в библиотеку и оборачивал вызов Whatever.GoGoGo () как в сервисе, так и в консольном приложении.
С чем-то, что вы запускаете каждые две минуты, шансы приличные, что это не так много (например, просто функция типа "пинг"). Обертки не должны содержать больше, чем один вызов метода и некоторое ведение журнала.
Это старый вопрос, но я хотел бы поделиться тем, с чем я столкнулся.
Недавно мне дали требование делать снимок экрана радара (с метеорологического веб-сайта) и сохранять его на сервере каждые 10 минут.
Это потребовало от меня использования WebBrowser. Обычно я создаю службы Windows, поэтому я решил сделать и эту службу, но она продолжала давать сбой. Это то, что я видел в пути к модулю просмотра событий : C: \ Windows \ system32 \ MSHTML.dll
Поскольку задача была срочной, и у меня было очень мало времени на исследования и эксперименты, я решил использовать простое консольное приложение и запустил его как задачу, и оно прошло гладко.
Мне очень понравилась статья Джона Галлоуэя, рекомендованная в принятом ответе Марком Рэнсомом.
Недавно пароли на серверах были изменены без моего подтверждения, и все службы не смогли выполнить, так как они не могли войти в систему. Итак, люди, утверждающие в комментариях к статье, что это проблема. Я думаю, что службы Windows могут столкнуться с той же проблемой (пожалуйста, поправьте меня, если я ошибаюсь, я просто новичок)
Также упомянутая вещь, если вы используете всплывающие окна планировщика задач или окно консоли. Я никогда с этим не сталкивался. Оно может всплывать, но, по крайней мере, мгновенно.
Как правило, основная идея заключается и должна заключаться в том, что сам код должен быть исполняемым от каждого «триггера / клиента». Так что переход от одного подхода к другому не должен быть ракетной наукой.
Раньше мы более или менее всегда использовали службы Windows, но поскольку все больше и больше наших клиентов переходят на Azure шаг за шагом, а переход с консольного приложения (развернутого как запланированная задача) на веб-задание в Azure намного проще, чем с Служба Windows, мы сейчас сосредоточены на запланированных задачах. Если мы сталкиваемся с ограничениями, мы просто расширяем проект службы Windows и вызываем ту же логику оттуда (пока клиенты работают с OnPrem ..) :)
BR, y
Службы Windows требуют больше терпения, пока это не будет сделано. Это немного жесткая отладка и установка. Это безлико. Если вам нужна задача, которая должна выполняться каждую секунду, минуту или час, вам следует выбрать службу Windows.
Запланированное задание быстро разрабатывается и имеет лицо. Если вам нужна ежедневная или еженедельная задача, вы можете использовать запланированную задачу.