Odpowiedzi:
Aktualizacja:
Prawie cztery lata po mojej pierwotnej odpowiedzi, a ta odpowiedź jest bardzo nieaktualna. Odkąd pojawił się TopShelf, rozwój usług Windows stał się łatwy. Teraz musisz tylko dowiedzieć się, jak obsługiwać przełączanie awaryjne ...
Oryginalna odpowiedź:
Naprawdę nie jestem fanem programu Windows Scheduler. Hasło użytkownika musi mieć postać @moodforall powyżej , co jest zabawne, gdy ktoś zmienia hasło tego użytkownika.
Inną poważną irytacją związaną z programem Windows Scheduler jest to, że działa on interaktywnie, a nie jako proces w tle. Gdy 15 okien MS-DOS pojawia się co 20 minut podczas sesji RDP, wyrzucisz sobie, że zamiast tego nie zainstalowałeś ich jako usług systemu Windows.
Cokolwiek wybierzesz, zdecydowanie zalecam rozdzielenie kodu przetwarzania na inny składnik z aplikacji konsoli lub usługi Windows. Następnie możesz wybrać, czy chcesz wywołać proces roboczy z aplikacji konsoli i podłączyć go do programu Windows Scheduler, czy użyć usługi systemu Windows.
Przekonasz się, że planowanie usługi systemu Windows nie jest zabawne. Dość powszechnym scenariuszem jest to, że masz długi proces, który chcesz uruchamiać okresowo. Ale jeśli przetwarzasz kolejkę, naprawdę nie chcesz, aby dwie instancje tego samego procesu roboczego przetwarzały tę samą kolejkę. Musisz więc zarządzać zegarem, aby upewnić się, że Twój długo działający proces działa dłużej niż przypisany interwał zegara, nie rozpocznie się on ponownie, dopóki istniejący proces nie zostanie zakończony.
Po napisaniu tego wszystkiego myślisz, dlaczego po prostu nie użyłem Thread.Sleep? Dzięki temu mogę pozwolić, aby bieżący wątek działał aż do zakończenia, a następnie włącza się przerwa, wątek przechodzi w stan uśpienia i ponownie się uruchamia po wymaganym czasie. Schludny!
Następnie czytasz wszystkie porady w Internecie, a wielu ekspertów mówi ci, jak to jest naprawdę zła praktyka programistyczna:
Więc podrapiesz się w głowę i pomyślisz sobie, WTF, Cofnij oczekujące kasy -> Tak, jestem pewien -> Cofnij całą dzisiejszą pracę ..... cholera, cholera, cholera ....
Jednak podoba mi się ten wzór, nawet jeśli wszyscy myślą, że to bzdura:
OnStart dla podejścia jednowątkowego.
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(); }
Kod tworzy instancję oddzielnego wątku i dołącza do niego naszą funkcję roboczą. Następnie uruchamia wątek i pozwala na zakończenie zdarzenia OnStart, aby system Windows nie pomyślał, że usługa jest zawieszona.
Metoda robocza dla podejścia jednowątkowego.
/// <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 dla podejścia jednowątkowego.
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)); }
Źródło: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)
Od lat korzystam z wielu takich usług Windows i to działa dla mnie. Nadal nie widziałem zalecanego wzoru, z którym ludzie się zgadzają. Po prostu rób to, co działa dla Ciebie.
NT AUTHORITY\NetworkService
jest konto z ograniczonymi uprawnieniami.
Tu trochę dezinformacji. Harmonogram systemu Windows doskonale nadaje się do uruchamiania zadań w tle bez wyskakujących okien i bez hasła. Uruchom go na koncie ZARZĄDZANIE NT \ SYSTEM. Użyj tego przełącznika schtasks:
/ ru SYSTEM
Ale tak, aby uzyskać dostęp do zasobów sieciowych, najlepszą praktyką jest konto usługi z oddzielną, nie wygasającą zasadą haseł.
EDYTOWAĆ
W zależności od systemu operacyjnego i wymagań samego zadania możesz mieć możliwość korzystania z kont mniej uprzywilejowanych niż system lokalny z /ru
opcją.
Z dobrej instrukcji ,
/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.
Harmonogram zadań 2.0 jest dostępny w wersjach Vista i Server 2008.
W XP i Server 2003 system
jest jedyną opcją.
Local Service
(aka NT AUTHORITY\LocalService
), a nie LocalSystem
(aka .\LocalSystem
). Ten pierwszy ma ograniczone prawa, drugi jest administratorem
LocalService
i NetworkService
są dostępne od schtasks
wersji v2 Vista i powinny być preferowane, jeśli to możliwe. W tym czasie odnosiło się to do schtasks
XP i Server 2003, które akceptują tylko System
parametr zgodnie ze starą wersją instrukcji technet.microsoft.com/en-us/library/bb490996.aspx
Jakie są koszty związane z uruchamianiem i zamykaniem aplikacji? Dość często co dwie minuty. Usługa prawdopodobnie pozwoliłaby systemowi działać płynniej niż częste wykonywanie aplikacji.
Oba rozwiązania mogą uruchamiać program, gdy użytkownik nie jest zalogowany, więc nie ma różnicy. Pisanie usługi jest jednak nieco bardziej skomplikowane niż zwykła aplikacja komputerowa - możesz potrzebować oddzielnego klienta GUI, który będzie komunikował się z aplikacją usługi za pośrednictwem protokołu TCP / IP, nazwanych potoków itp.
Z punktu widzenia użytkownika zastanawiam się, który jest łatwiejszy do kontrolowania. Zarówno usługi, jak i zaplanowane zadania są prawie poza zasięgiem większości nietechnicznych użytkowników, tj. Nawet nie zdają sobie sprawy, że istnieją i mogą zostać skonfigurowane / zatrzymane / przełożone i tak dalej.
W programowaniu .NET zwykle zaczynam od stworzenia aplikacji konsoli, która będzie uruchamiać wszystkie dane wyjściowe logowania do okna konsoli. Jest to jednak aplikacja konsolowa tylko wtedy, gdy jest uruchamiana z argumentem polecenia /console
. Gdy jest uruchamiany bez tego parametru, działa jako usługa systemu Windows, która będzie działać z moim własnym, niestandardowym, zaplanowanym zegarem.
Myślę, że usługi Windows są zwykle używane do zarządzania innymi aplikacjami, a nie są długotrwałą aplikacją. LUB .. są to stale działające aplikacje o dużej gramaturze, takie jak SQL Server, BizTalk, połączenia RPC, IIS (mimo że usługi IIS technicznie odciążają pracę innych procesów).
Osobiście wolę zaplanowane zadania niż usługi Windows w przypadku powtarzalnych zadań konserwacyjnych i aplikacji, takich jak kopiowanie / synchronizacja plików, masowe wysyłanie wiadomości e-mail, usuwanie lub archiwizacja plików, korekta danych (gdy inne obejścia nie są dostępne).
W jednym projekcie byłem zaangażowany w rozwój 8 lub 9 usług Windows, ale są one przechowywane w pamięci, bezczynne, zużywając 20 MB lub więcej pamięci na instancję. Zaplanowane zadania załatwią sprawę i natychmiast zwolnią pamięć.
Słowo „usługa” ma coś wspólnego z „serwerem”. Oczekuje się, że zawsze będzie działał i służył. Zadanie to zadanie.
Odgrywanie ról. Jeśli jestem innym systemem operacyjnym, aplikacją lub urządzeniem i dzwonię do usługi, spodziewam się, że działa i oczekuję odpowiedzi. Jeśli ja (os, app, dev) muszę tylko wykonać pojedyncze zadanie, wykonam zadanie, ale jeśli spodziewam się komunikacji, być może dwukierunkowej, chcę usługi. Ma to związek z najbardziej efektywnym sposobem komunikowania się dwóch rzeczy lub jednej rzeczy, która chce wykonać jedno zadanie.
Jest też aspekt planowania. Jeśli chcesz, aby coś działało o określonej godzinie, zaplanuj. Jeśli nie wiesz, kiedy będziesz go potrzebować lub kiedy będziesz go potrzebować „w locie”, skorzystaj z serwisu.
Moja odpowiedź ma bardziej filozoficzny charakter, ponieważ jest bardzo podobna do tego, jak ludzie wchodzą w interakcje i pracują z innymi. Im lepiej rozumiemy sztukę komunikacji, a „byty” rozumieją swoją rolę, tym łatwiejsza staje się ta decyzja.
Pomijając całą filozofię, kiedy „szybko prototypujesz”, jak to często robi mój dział IT, robisz wszystko, co musisz, aby związać koniec z końcem. Gdy prototypowanie i weryfikacja koncepcji znikną z drogi, zwykle na wczesnym etapie planowania i odkrywania, musisz zdecydować, co jest bardziej niezawodne dla długoterminowego zrównoważonego rozwoju.
OK, więc podsumowując, jest to wysoce zależne od wielu czynników, ale miejmy nadzieję, że dostarczyło to wglądu zamiast zamieszania.
Usługa Windows nie musi nikogo logować, a system Windows ma funkcje zatrzymywania, uruchamiania i rejestrowania wyników usługi.
Zaplanowane zadanie nie wymaga nauki pisania usługi systemu Windows.
NT AUTHORITY\LocalService
lub NT AUTHORITY\NetworkService
). Każde podane hasło jest ignorowane, ponieważ konta nie mają hasła.
Dlaczego nie zapewnić obu?
W przeszłości umieściłem bity „rdzenia” w bibliotece i zawarłem wywołanie Whaters.GoGo () zarówno w usłudze, jak i aplikacji konsolowej.
Z czymś, co odpalasz co dwie minuty, szanse są przyzwoite, to niewiele (np. Funkcja typu „ping”). Opakowania nie powinny zawierać więcej niż jedno wywołanie metody i trochę rejestrowania.
To stare pytanie, ale chciałbym się podzielić tym, z czym się zmierzyłem.
Ostatnio dostałem wymóg wykonania zrzutu ekranu radaru (ze strony internetowej Meteorologicznej) i zapisywania go na serwerze co 10 minut.
Wymagało to używania WebBrowser. Zwykle tworzę usługi Windows, więc zdecydowałem się zrobić tę jedną usługę, ale ciągle się zawieszała. Oto, co widziałem w Podglądzie zdarzeń ścieżce modułu Faulting: C: \ Windows \ system32 \ MSHTML.dll
Ponieważ zadanie było pilne i miałem bardzo mniej czasu na badania i eksperymenty, zdecydowałem się użyć prostej aplikacji konsolowej, uruchomiłem ją jako zadanie i wykonałem ją płynnie.
Bardzo podobał mi się artykuł Jona Gallowaya polecany w zaakceptowanej odpowiedzi przez Marka Ransoma.
Ostatnio hasła na serwerach zostały zmienione bez potwierdzania mnie, a wszystkie usługi nie działały, ponieważ nie mogły się zalogować. Więc ppl twierdząc w artykule komentuje, że jest to problem. Myślę, że usługi systemu Windows mogą napotkać ten sam problem (proszę poprawić mnie, jeśli się mylę, jestem nowicjuszem)
Wspomniano również o tym, że jeśli używasz harmonogramu zadań, wyskakuje okno lub wyskakuje okno konsoli. Nigdy się z tym nie spotkałem. Może się pojawić, ale jest co najmniej bardzo natychmiastowe.
Ogólnie rzecz biorąc, głównym przesłaniem jest i powinno być to, że sam kod musi być wykonywalny z każdego „wyzwalacza / klienta”. Zatem przejście z jednego podejścia na drugie nie powinno być fizyką rakietową.
W przeszłości korzystaliśmy prawie zawsze z usług Windows, ale ponieważ coraz więcej naszych klientów przechodzi na platformę Azure krok po kroku, a zamiana aplikacji konsolowej (wdrożonej jako zaplanowane zadanie) na zadanie WebJob na platformie Azure jest znacznie łatwiejsza niż z Usługa Windows, na razie skupiamy się na zaplanowanych zadaniach. Jeśli napotkamy ograniczenia, po prostu przyspieszamy projekt usługi Windows i wywołujemy tę samą logikę (o ile klienci pracują OnPrem ..) :)
BR, y
Usługi systemu Windows wymagają więcej cierpliwości, dopóki nie zostaną ukończone. Ma trochę trudnego debugowania i instalacji. Jest bez twarzy. Jeśli potrzebujesz zadania, które trzeba wykonać co sekundę, minutę lub godzinę, wybierz usługę Windows.
Zaplanowane zadanie jest szybko rozwijane i ma twarz. Jeśli potrzebujesz zadania dziennego lub cotygodniowego, możesz użyć Zaplanowane zadanie.