2016-09-19 2 views
0

Ich schreibe einen Windows-Dienst in .NET Framework 4.0 und ich muß innerhalb einer wiederkehrende Aufgabe planen. Neue Aufgabe kann nur ausgeführt werden, wenn die vorherige abgeschlossen ist, also keine Aufgaben parallel ... Alle Aufgaben meiner Aufgabe arbeiten an demselben Objekt (WCF Channel Factory). Eine Aufgabe dauert fast 2 Sekunden und kann alle 2 Sekunden oder jede Stunde geplant werden. Meine Einschränkung ist diese Windows-Dienst als unsichtbar/Licht wie möglich auf Speicher und Prozessor verwendet Sicht zu haben ...C# Die beste Weg, in einem effizienten Windows-Dienst wiederkehrende Aufgabe planen

ich bereits habe diese 2 Möglichkeiten gefunden:

  • Verwenden Sie ein System.Timers.Timer mit Autoreset nicht sicher Aspekt in dass Zustand mem/proc Verwendung aber keine Threads darauf achten: auf false => ich habe
  • Verwenden Sie einen nicht enden wollenden Schleife eine ElapsedEventHandler und übergeben mein gemeinsames Objekt (WCF Channel-Fabrik) implementieren von.

Irgendwelche Vorschläge?

Dank und einen schönen Tag!

+0

Hier ist eine Möglichkeit, wiederkehrende Aufgaben mit der TPL implementiert. Es könnte Ihnen eine andere Idee/Route geben. http://stackoverflow.com/q/39457595/2985796 – KDecker

Antwort

2

Für mich war in Ordnung folgende: Im begann einmal Timer, dann in Tick-Methode werde ich nächsten Tick Anruf planen. Wie folgt aus:

public void SetTimer() 
{ 
    // this is System.Threading.Timer, ofcource 
    _timer = new Timer(Tick, null, _interval, Timeout.Infinite); 
} 

private void Tick(object state) 
{ 
    try 
    { 
     // do your stuff 
    } 
    finally 
    { 
     _timer?.Change(_interval, Timeout.Infinite); 
    } 
} 

// dont forget to dispose your timer. 
+0

Dank Tym, nehme ich an, dass ich neue System.Threading.Timer haben sollte ich (Tick, MyWCFSharedObject, _interval, Timeout.Infinite) in meinem Fall ... Wenn ok, hoffe, dass alle Änderungen, die an meiner MyWCFSharedObject-Methode innerhalb der Tick-Methode vorgenommen wurden, auf Windows-Service-Ebene sichtbar sind? – Francois

+0

Tick - nur Funktion, Sie können es sichtbar auf aly Ebene machen, können Sie Event in der Lage, es öffentlich zu machen, wenn Sie das wirklich brauchen. – tym32167

+0

tatsächlich, als Beispiel, wo ich verwenden, um diesen, https://github.com/tym32167/arma3beclient/blob/develop/src/Arma3BE.Client.Modules.BEServerModule/BEServiceLogic.cs#L108 – tym32167

1

System.Timers.Timer ist der Weg zu gehen und wird wenig bis gar keine Systemleistung auswirken. Gegenwärtige Systeme können Tausende von Zeitgebern handhaben.

Da Sie die Timer fortsetzen wollen, Autoreset nicht gesetzt, aber Sie werden einen Weg brauchen das Intervall zu ändern (wenn es das ist, was Sie brauchen).

Ihre Service-Instanz sollte eine Instanz Ihrer WCF Kanalfactory halten.

Um eine synchrone Verarbeitung zu gewährleisten, sollten Sie ein geschütztes Flag Interlocked implementieren, das als Indikator für die Betriebsbereitschaft dient. Wenn sie gleich Eins ist, wird zum Beispiel die Methode, die die Verarbeitung des abgelaufenen Timer-Ereignisses startet, einfach zurückkehren. Wenn die Verarbeitung abgeschlossen ist und Sie das Flag zu diesem Zeitpunkt auf Null setzen, können weitere abgelaufene Timer-Ereignisse eintreten und die Verarbeitung erneut starten.

Denken Sie daran, neu starten, zu stoppen und Ihr Timer in den verschiedenen Serviceereignissen verfügt, wie Pause, Stopp, starten.

+0

Interessant. Natürlich ist mein WCF-Kanal-Factory-Objekt auf Windows-Service-Ebene definiert. Ich stimme Ihrem Vorschlag ohne AutoReset zu, es ist ein anderer Weg, damit umzugehen. Aber ich verstehe nicht, warum ich eine Interlock-Behandlung brauche, da in meinem Fall keine parallelen Aufgaben auftreten können. – Francois

+0

Ich denke, dass Sie in dieser Lösung Interlocked verwenden müssen, da während Sie dieses Flag lesen, ein anderer Thread in der Lage ist, darauf zu schreiben. Wenn Sie in einem Thread in den Speicher schreiben und diesen aus einem anderen Thread lesen müssen, sollten Sie Thread-sichere Konstruktionen verwenden. Interlocked ist gut, um sicheres Lesen/Schreiben zu dieser Flagge zu führen. – tym32167

+0

Ok ... Und ich habe gerade gedacht, dass ich möglicherweise gleichzeitige Speicherzugriffe in OnStop() oder OnSessionChanged() -Methoden meines Windows-Dienstes zum Beispiel habe ... Ich habe ein paar Dunkelheit Punkte bezüglich Interlock, also wollte ich vermeiden sie ... :) – Francois

Verwandte Themen