Antworten:
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:
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.
NT AUTHORITY\NetworkService
ist ein Konto mit eingeschränkten Berechtigungen.
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 /ru
Option 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 system
ist dies die einzige Option.
Local Service
(aka NT AUTHORITY\LocalService
) anstatt als LocalSystem
(aka .\LocalSystem
). Ersterer hat eingeschränkte Rechte, während letzterer Administrator ist
LocalService
und NetworkService
sind in verfügbar schtasks
v2 Vista ab und sollte , wenn möglich vorzuziehen. Zu der Zeit bezog sich dies auf die schtasks
in XP und Server 2003, die nur System
als Parameter gemäß dem alten Versionshandbuch technet.microsoft.com/en-us/library/bb490996.aspx
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.
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.
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.
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.
NT AUTHORITY\LocalService
oder NT AUTHORITY\NetworkService
). Jedes angegebene Kennwort wird ignoriert, da die Konten kein Kennwort haben.
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.
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.
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
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.