Windows-Dienst gegen geplante Aufgabe


115

Was sind die Vor- und Nachteile von Windows-Diensten gegenüber geplanten Aufgaben beim wiederholten Ausführen eines Programms (z. B. alle zwei Minuten)?

Antworten:


51

Aktualisieren:

Fast vier Jahre nach meiner ursprünglichen Antwort und diese Antwort ist sehr veraltet. Seit der Einführung von TopShelf wurde die Entwicklung von Windows Services einfach. Jetzt müssen Sie nur noch herausfinden, wie Sie Failover unterstützen können ...

Ursprüngliche Antwort:

Ich bin wirklich kein Fan von Windows Scheduler. Das Kennwort des Benutzers muss wie oben angegeben mit @moodforall angegeben werden. Dies macht Spaß, wenn jemand das Kennwort dieses Benutzers ändert.

Das andere große Ärgernis bei Windows Scheduler ist, dass es interaktiv und nicht als Hintergrundprozess ausgeführt wird. Wenn während einer RDP-Sitzung alle 20 Minuten 15 MS-DOS-Fenster angezeigt werden, treten Sie sich selbst in die Knie, wenn Sie sie nicht stattdessen als Windows-Dienste installiert haben.

Was auch immer Sie wählen, ich empfehle Ihnen auf jeden Fall, Ihren Verarbeitungscode in eine andere Komponente als die Konsolen-App oder den Windows-Dienst aufzuteilen. Dann haben Sie die Wahl, entweder den Worker-Prozess von einer Konsolenanwendung aus aufzurufen und in den Windows Scheduler einzubinden oder einen Windows-Dienst zu verwenden.

Sie werden feststellen, dass das Planen eines Windows-Dienstes keinen Spaß macht. Ein ziemlich häufiges Szenario ist, dass Sie einen lang laufenden Prozess haben, den Sie regelmäßig ausführen möchten. Wenn Sie jedoch eine Warteschlange verarbeiten, möchten Sie wirklich nicht, dass zwei Instanzen desselben Workers dieselbe Warteschlange verarbeiten. Sie müssen also den Timer verwalten, um sicherzustellen, dass Ihr lang laufender Prozess länger als das zugewiesene Timer-Intervall ausgeführt wird und erst wieder gestartet wird, wenn der vorhandene Prozess abgeschlossen ist.

Nachdem Sie das alles geschrieben haben, denken Sie, warum habe ich nicht einfach Thread.Sleep verwendet? Dadurch kann ich den aktuellen Thread so lange laufen lassen, bis er beendet ist, und dann beginnt das Pausenintervall, der Thread geht in den Ruhezustand und startet nach der erforderlichen Zeit wieder. Ordentlich!

Dann lesen Sie alle Ratschläge im Internet mit vielen Experten, die Ihnen sagen, wie schlecht die Programmierpraxis ist:

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

Also kratzen Sie sich am Kopf und denken sich, WTF, Pending Checkouts rückgängig machen -> Ja, ich bin sicher -> Alle heutigen Arbeiten rückgängig machen ..... verdammt, verdammt, verdammt ....

Ich mag dieses Muster jedoch, auch wenn jeder denkt, es sei Mist:

OnStart-Methode für den Single-Thread-Ansatz.

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();
}

Der Code instanziiert einen separaten Thread und hängt unsere Worker-Funktion daran an. Dann wird der Thread gestartet und das OnStart-Ereignis abgeschlossen, sodass Windows nicht glaubt, dass der Dienst hängen bleibt.

Worker-Methode für den Single-Thread-Ansatz.

/// <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-Methode für den Single-Thread-Ansatz.

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));
}

Quelle: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)

Ich habe jahrelang viele solcher Windows-Dienste ausgeführt und es funktioniert für mich. Ich habe immer noch kein empfohlenes Muster gesehen, über das sich die Leute einig sind. Mach einfach, was für dich funktioniert.


2
Möglicherweise möchten Sie Ihren Dienst mit einem eigenen Dienstkonto ausführen. Wenn auf allem ein SERVICE oder NETWORKSERVICE ausgeführt wird, erteilen Sie Ihrer App Berechtigungen, die sie wahrscheinlich nicht benötigt (und die die Sicherheit nicht nur eines Servers, sondern Ihres gesamten Netzwerks gefährden können).
Matthew Whited

1
Tatsächlich. Ich glaube nicht, dass ich etwas anderes gesagt habe?
Rebecca

4
Sie haben in Ihrem ersten Absatz etwas anderes impliziert. Das Kennwort des Benutzers ist für Dienste genauso erforderlich wie für den Taskplaner, wenn Sie keines der integrierten Konten verwenden.
Nick Cox

1
@MatthewWhited Das NT AUTHORITY\NetworkServiceist ein Konto mit eingeschränkten Berechtigungen.
Ian Boyd

1
@IanBoyd einschließlich aller Berechtigungen, die NetworkService für andere Anwendungen zugewiesen wurden.
Matthew Whited

16

Einige Fehlinformationen hier. Windows Scheduler ist perfekt in der Lage, Aufgaben im Hintergrund auszuführen, ohne dass Windows auftaucht und kein Kennwort erforderlich ist. Führen Sie es unter dem Konto NT AUTHORITY \ SYSTEM aus. Verwenden Sie diesen schtasks-Schalter:

/ ru SYSTEM

Ja, für den Zugriff auf Netzwerkressourcen empfiehlt sich ein Dienstkonto mit einer separaten Kennwortrichtlinie, die nicht abläuft.

BEARBEITEN

Abhängig von Ihrem Betriebssystem und den Anforderungen der Aufgabe selbst können Sie mit dieser /ruOption möglicherweise Konten verwenden, die weniger privilegiert sind als Localsystem .

Aus dem feinen Handbuch ,

/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 ist unter Vista und Server 2008 verfügbar.

In XP und Server 2003 systemist dies die einzige Option.


2
Bitte laufen Sie als Local Service(aka NT AUTHORITY\LocalService) anstatt als LocalSystem(aka .\LocalSystem). Ersterer hat eingeschränkte Rechte, während letzterer Administrator ist
Ian Boyd

1
Ja , die zusätzlichen Konten LocalServiceund NetworkServicesind in verfügbar schtasksv2 Vista ab und sollte , wenn möglich vorzuziehen. Zu der Zeit bezog sich dies auf die schtasksin XP und Server 2003, die nur Systemals Parameter gemäß dem alten Versionshandbuch technet.microsoft.com/en-us/library/bb490996.aspx
Amit Naidu

Unter XP können Sie geplante Aufgaben nicht als SYSTEM ausführen. Viel Glück damit. Dieser fasst es gut zusammen: cwl.cc/2011/12/run-scheduled-task-as-system.html
Pupsik

11

Was ist der Aufwand für das Starten und Beenden der App? Alle zwei Minuten ist ziemlich oft. Ein Dienst würde das System wahrscheinlich reibungsloser laufen lassen als die häufige Ausführung Ihrer Anwendung.

Beide Lösungen können das Programm ausführen, wenn der Benutzer nicht angemeldet ist, also kein Unterschied. Das Schreiben eines Dienstes ist jedoch etwas aufwendiger als eine normale Desktop-App. Möglicherweise benötigen Sie einen separaten GUI-Client, der über TCP / IP, Named Pipes usw. mit der Dienst-App kommuniziert.

Aus der POV eines Benutzers frage ich mich, welche einfacher zu steuern ist. Sowohl Dienste als auch geplante Aufgaben sind für die meisten nicht-technischen Benutzer so gut wie unerreichbar, dh sie erkennen nicht einmal, dass sie vorhanden sind, und können konfiguriert / gestoppt / neu geplant werden und so weiter.


10

In der .NET-Entwicklung beginne ich normalerweise mit der Entwicklung einer Konsolenanwendung, die alle Protokollausgaben im Konsolenfenster ausführt. Dies ist jedoch nur eine Konsolenanwendung, wenn sie mit dem Befehlsargument ausgeführt wird /console. Wenn es ohne diesen Parameter ausgeführt wird, fungiert es als Windows-Dienst, der auf meinem eigenen benutzerdefinierten codierten geplanten Timer ausgeführt wird.

Ich denke, Windows-Dienste werden normalerweise zum Verwalten anderer Anwendungen verwendet, anstatt eine lang laufende Anwendung zu sein. ODER .. Sie führen kontinuierlich Schwergewichtsanwendungen wie SQL Server, BizTalk, RPC-Verbindungen und IIS aus (obwohl IIS technisch auf andere Prozesse ausgelagert ist).

Persönlich bevorzuge ich geplante Aufgaben gegenüber Windows Services für sich wiederholende Wartungsaufgaben und -anwendungen wie das Kopieren / Synchronisieren von Dateien, das Versenden von Massen-E-Mails, das Löschen oder Archivieren von Dateien und die Datenkorrektur (wenn andere Problemumgehungen nicht verfügbar sind).

Für ein Projekt war ich an der Entwicklung von 8 oder 9 Windows-Diensten beteiligt, aber diese sitzen im Speicher, im Leerlauf und verbrauchen 20 MB oder mehr Speicher pro Instanz. Geplante Aufgaben erledigen ihr Geschäft und geben den Speicher sofort frei.


8

Das Wort "serv'ice" hat etwas mit "serv'er" gemeinsam. Es wird erwartet, dass es immer läuft und "dient". Eine Aufgabe ist eine Aufgabe.

Rollenspiel. Wenn ich ein anderes Betriebssystem, eine andere Anwendung oder ein anderes Gerät bin und einen Dienst anrufe, erwarte ich, dass dieser ausgeführt wird, und erwarte eine Antwort. Wenn ich (os, app, dev) nur eine isolierte Aufgabe ausführen muss, werde ich eine Aufgabe ausführen, aber wenn ich eine Kommunikation erwarte, möglicherweise eine bidirektionale Kommunikation, möchte ich einen Dienst. Dies hat mit der effektivsten Art der Kommunikation zwischen zwei Dingen oder einer einzelnen Sache zu tun, die eine einzelne Aufgabe ausführen möchte.

Dann gibt es den Planungsaspekt. Wenn Sie möchten, dass etwas zu einer bestimmten Zeit ausgeführt wird, planen Sie. Wenn Sie nicht wissen, wann Sie es brauchen oder "on the fly" brauchen, Service.

Meine Antwort ist eher philosophischer Natur, weil dies sehr ähnlich ist, wie Menschen mit anderen interagieren und arbeiten. Je besser wir die Kunst der Kommunikation verstehen und "Entitäten" ihre Rolle verstehen, desto einfacher wird diese Entscheidung.

Abgesehen von der Philosophie tun Sie, wenn Sie "Rapid Prototyping" betreiben, wie es meine IT-Abteilung oft tut, alles, um über die Runden zu kommen. Sobald das Prototyping und Proof-of-Concept-Material aus dem Weg geräumt ist, normalerweise in der frühen Planung und Entdeckung, müssen Sie entscheiden, was für eine langfristige Nachhaltigkeit zuverlässiger ist.

OK, abschließend ist es in hohem Maße von vielen Faktoren abhängig, aber hoffentlich hat dies Einsicht statt Verwirrung gebracht.


4

Bei einem Windows-Dienst muss niemand angemeldet sein, und Windows verfügt über Funktionen zum Stoppen, Starten und Protokollieren der Dienstergebnisse.

Für eine geplante Aufgabe müssen Sie nicht lernen, wie Sie einen Windows-Dienst schreiben.


9
Geplante Aufgaben können auch ausgeführt werden, ohne dass der Benutzer angemeldet ist. Das Kennwort des Benutzers muss jedoch dem Planungsagenten mitgeteilt werden.
Marek Jedliński

1
@moodforaday Es sei denn, für das Konto wurde keine Konfiguration bestanden (z . B. NT AUTHORITY\LocalServiceoder NT AUTHORITY\NetworkService). Jedes angegebene Kennwort wird ignoriert, da die Konten kein Kennwort haben.
Ian Boyd

4
  1. Es ist einfacher, Windows-Dienste mit den richtigen Berechtigungen einzurichten und zu sperren.
  2. Services sind "sichtbarer", was bedeutet, dass jeder (dh Techniker) weiß, wo er suchen muss.

5
Ihr erster Punkt gilt auch für geplante Aufgaben. Ich bin mir nicht sicher, was "sichtbarer" bedeutet. Geplante Aufgaben können genauso einfach angezeigt werden wie Dienste.
w4g3n3r

@ w4g3n3r: Die meisten Techniker wissen, wie man Windows-Dienste betrachtet, um zu sehen, was läuft. Wenn es sich um einen Dienst handelt (und ausgeführt wird), wird er in der normalen Task-Manager-Liste angezeigt. Sehr sehr wenige Leute verwenden jemals geplante Aufgaben.
NotMe

Außerdem wissen die Techniker, dass sie in der Ereignisanzeige nachsehen müssen, wenn ein Problem auftritt. Geplante Aufgaben speichern diese Informationen in einer Protokolldatei im Dateisystem. Ich bin bereit zu wetten, dass die meisten Leute nicht einmal wissen würden, wo sie danach suchen sollen.
NotMe

1
Ich würde nicht zustimmen über "Sehr sehr wenige Leute verwenden jemals geplante Aufgaben", es sei denn, Sie haben Statistiken. Ich sehe sie die ganze Zeit. Für Nicht-Codierer, die alle 2 Minuten etwas ausführen müssen, navigieren sie einfach zu Geplante Aufgaben (dieselbe Schwierigkeit wie beim Aufrufen von Diensten), aber um eine neue zu erstellen, gibt es einen Assistenten. Sie müssen also nur wissen, wo sich das Programm oder Skript befindet und wie oft es ausgeführt werden soll. Wenn Sie nun wissen, wie man codiert und den Computer in einem Netzwerk hat, die Anmeldung schützen müssen, eine integrierte Behandlung benötigen, um mehrere Instanzen zu verhindern (wenn eine über 2 Minuten ausgeführt wird), würde ich mich für einen Dienst entscheiden.
Gary

4
„ Die meisten Tech - Leute wissen , wie bei Windows - Dienste , um zu sehen , was läuft“ . Das ist eines der Probleme mit Dienstleistungen; Sie führen ständig zeitaufwändige Benutzer- und Kernelressourcen aus, nur um einen laufenden Prozess zu speichern. Aus diesem Grund hat Microsoft so viele Dienste wie möglich zu einem einzigen Prozess zusammengeführt ( svchost.exe ). unnötigen Ressourcenverbrauch einfach durch Prozesse zu beseitigen.
Ian Boyd

2

Warum nicht beides anbieten?

In der Vergangenheit habe ich die 'Kern'-Bits in eine Bibliothek gestellt und einen Aufruf von Whatever.GoGoGo () sowohl in einem Dienst als auch in einer Konsolen-App verpackt.

Mit etwas, das Sie alle zwei Minuten abfeuern, stehen die Chancen gut, dass es nicht viel bringt (z. B. nur eine "Ping" -Funktion). Die Wrapper sollten nicht viel mehr als einen einzelnen Methodenaufruf und einige Protokollierungen enthalten müssen.


2

Dies ist eine alte Frage, aber ich möchte mitteilen, was ich gesehen habe.

Kürzlich wurde mir die Anforderung gestellt, den Screenshot eines Radars (von einer meteorologischen Website) aufzunehmen und alle 10 Minuten auf dem Server zu speichern.

Dafür musste ich WebBrowser verwenden. Normalerweise mache ich Windows-Dienste, also habe ich beschlossen, auch diesen einen Dienst zu machen, aber er würde immer wieder abstürzen. Folgendes habe ich im Pfad des Moduls "Fehleranzeige für Ereignisanzeige" gesehen : C: \ Windows \ system32 \ MSHTML.dll

Da die Aufgabe dringend war und ich weniger Zeit zum Forschen und Experimentieren hatte, entschied ich mich für eine einfache Konsolenanwendung und löste sie als Aufgabe aus, und sie wurde reibungslos ausgeführt.

Der Artikel von Jon Galloway , der in der akzeptierten Antwort von Mark Ransom empfohlen wurde, hat mir sehr gut gefallen .

Kürzlich wurden Kennwörter auf den Servern geändert, ohne mich zu bestätigen, und alle Dienste konnten nicht ausgeführt werden, da sie sich nicht anmelden konnten. Also behauptet ppl in den Artikelkommentaren, dass dies ein Problem ist. Ich denke, Windows-Dienste können das gleiche Problem haben (Bitte korrigieren Sie mich, wenn ich falsch liege, ich bin nur ein Neuling)

Auch die erwähnte Sache, wenn Taskplaner-Fenster auftauchen oder das Konsolenfenster erscheint. Ich habe mich dem nie gestellt. Es kann auftauchen, ist aber zumindest sehr augenblicklich.


Ich dachte, Jon Galloways Artikel machte einige gute Punkte. Bei Beschwerden über geplante Aufgaben, die aufgrund einer Kennwortänderung oder aus anderen Gründen nicht ausgeführt werden können, ist es auch möglich, auf eine geplante Aufgabe zu antworten, die nicht ausgeführt werden kann, sodass Sie Benutzer benachrichtigen können oder was auch immer Sie tun möchten. Siehe Lösung hier: superuser.com/questions/249103/...
Dan Csharpster

1

Im Allgemeinen lautet und sollte die Kernbotschaft lauten, dass der Code selbst von jedem einzelnen "Trigger / Client" ausführbar sein muss. Es sollte also keine Raketenwissenschaft sein, von einem zum anderen Ansatz zu wechseln.

In der Vergangenheit haben wir mehr oder weniger immer Windows-Dienste verwendet, aber da auch immer mehr unserer Kunden Schritt für Schritt zu Azure wechseln und der Wechsel von einer Konsolen-App (die als geplante Aufgabe bereitgestellt wird) zu einem WebJob in Azure viel einfacher ist als von Als Windows-Dienst konzentrieren wir uns vorerst auf geplante Aufgaben. Wenn wir auf Einschränkungen stoßen, fahren wir einfach das Windows-Dienstprojekt hoch und rufen von dort aus dieselbe Logik auf (solange Kunden an OnPrem arbeiten ..) :)

BR, y


0

Windows-Dienste möchten mehr Geduld, bis dies erledigt ist. Es hat ein bisschen hartes Debuggen und Installieren. Es ist gesichtslos. Wenn Sie eine Aufgabe benötigen, die in jeder Sekunde, Minute oder Stunde ausgeführt werden muss, sollten Sie Windows-Dienst auswählen.

Geplante Aufgabe ist schnell entwickelt und hat ein Gesicht. Wenn Sie eine tägliche oder wöchentliche Aufgabe benötigen, können Sie die geplante Aufgabe verwenden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.