Wie würden Sie meinen in C # geschriebenen Heartbeat-Prozess ändern?

8

Ich bin dabei, einen "Heartbeat" -Prozess zu implementieren, um im Laufe des Tages viele wiederholte Aufräumarbeiten durchzuführen.

Dies schien eine gute Gelegenheit zu sein, das Befehlsmuster zu verwenden, also habe ich eine Schnittstelle, die wie folgt aussieht:

%Vor%

Ich habe dann mehrere Aufgaben erstellt, die ich ausführen möchte. Hier ist ein einfaches Beispiel:

%Vor%

Schließlich läuft meine Konsolenanwendung in dieser Schleife nach wartenden Aufgaben, die dem ThreadPool hinzugefügt werden sollen:

%Vor%

Ich habe nicht viel Erfahrung mit Multithreading, abgesehen von der Arbeit, die ich in der Klasse Betriebssysteme geleistet habe. Soweit ich feststellen kann, greift jedoch keiner meiner Threads auf einen freigegebenen Zustand zu, so dass sie in Ordnung sein sollten.

Scheint das wie ein "OK" Entwurf für das, was ich tun möchte? Gibt es irgendetwas, was du ändern würdest?

    
mmcdole 27.01.2010, 02:29
quelle

5 Antworten

10

Das ist ein guter Anfang. Wir haben in letzter Zeit eine Menge Dinge getan, damit ich ein paar Vorschläge machen kann.

  1. Verwenden Sie den Threadpool nicht für lange laufende Aufgaben. Der Thread-Pool ist so konzipiert, dass er viele kleine Aufgaben ausführt. Wenn Sie Aufgaben mit langer Laufzeit ausführen, verwenden Sie einen separaten Thread. Wenn Sie den Thread-Pool verhungern (alle Aufgaben verwenden), wartet alles, was in die Warteschlange gestellt wird, nur auf die Verfügbarkeit eines Threadpool-Threads, was sich erheblich auf die effektive Leistung des Threadpools auswirkt.

  2. Lassen Sie die Main () Routine im Auge behalten, wann die Dinge gelaufen sind und wie lange sie bis zum nächsten laufen. Anstatt dass jeder Befehl sagt: "Ja, ich bin bereit" oder "Nein, ich bin nicht", was für jeden Befehl derselbe sein wird, habe nur LastRun und Intervall-Felder, die Main () dann verwenden kann, um zu bestimmen, wann jeder Befehl ausgeführt werden muss .

  3. Verwenden Sie keine Warteschlange. Während es wie eine Warteschlangentyp-Operation aussieht, da jeder Befehl sein eigenes Intervall hat, ist es wirklich keine normale Warteschlange. Platziere stattdessen alle Befehle in einer Liste und sortiere die Liste dann nach der kürzesten Zeit zum nächsten Lauf. Schlaf den Thread, bis der erste Befehl zum Ausführen benötigt wird. Führen Sie diesen Befehl aus. Rufen Sie die Liste mit dem nächsten Befehl auf, um sie auszuführen. Schlaf. Wiederholen.

  4. Verwenden Sie nicht mehrere Threads. Wenn das Intervall jedes Befehls eine Minute oder einige Minuten ist, müssen Sie wahrscheinlich überhaupt keine Threads verwenden. Sie können vereinfachen, indem Sie alles im selben Thread tun.

  5. Fehlerbehandlung. Diese Art von Sache benötigt eine umfassende Fehlerbehandlung, um sicherzustellen, dass ein Problem in einem Befehl nicht die gesamte Schleife zum Scheitern bringt, und Sie so ein Problem debuggen können, wenn es auftritt. Vielleicht möchten Sie auch entscheiden, ob ein Befehl sofort bei einem Fehler erneut versucht werden soll oder bis zum nächsten geplanten Lauf warten soll oder ob es sogar mehr als normal verzögert werden soll. Sie können auch keinen Fehler in einem Befehl protokollieren, wenn der Fehler jedes Mal auftritt (ein Fehler in einem Befehl, der häufig ausgeführt wird, kann problemlos große Protokolldateien erstellen).

Samuel Neff 27.01.2010, 02:39
quelle
6

Anstatt alles von Grund auf neu zu schreiben, können Sie Ihre Anwendung mit einem Framework erstellen, das alle Zeitpläne und Threads für Sie übernimmt. Die Open-Source-Bibliothek NCron wurde für genau diesen Zweck entwickelt und ist sehr einfach zu bedienen.

Definieren Sie Ihren Job so:

%Vor%

Und erstellen Sie einen Haupteingangspunkt für Ihre Anwendung einschließlich Zeitplaneinstellungen wie folgt:

%Vor%

Dies ist all der Code, den Sie schreiben müssen, wenn Sie diesen Pfad wählen. Sie können auch komplexere Zeitpläne oder Abhängigkeitseinspeisung falls erforderlich und Protokollierung ist sofort einsatzbereit.

Disclaimer: Ich bin der leitende Programmierer auf NCron, also könnte ich nur ein bisschen voreingenommen sein! ; -)

    
Jørn Schou-Rode 29.01.2010 23:21
quelle
2

Ich würde alle Ihre Befehlsklassen unveränderlich machen, um sicherzustellen, dass Sie sich keine Gedanken über Statusänderungen machen müssen.

    
LWoodyiii 27.01.2010 02:41
quelle
2

Jetzt sollten parallele Erweiterungen von Microsoft in Tagen die praktikable Option sein, um gleichzeitig Code zu schreiben oder threadbezogene Aufgaben zu erledigen. Es bietet eine gute Abstraktion oberhalb von Thread-Pool- und System-Threads, sodass Sie nicht gezwungen werden müssen, die Aufgabe zu erledigen.

Meiner Meinung nach, es zu benutzen. Der Code ist übrigens sauber.

Danke.

    
Anand Patel 17.02.2010 07:11
quelle
0

running variable muss als volatile markiert werden, wenn ihr Status von einem anderen Thread geändert wird.

Was die Eignung betrifft, warum nicht einfach einen Timer verwenden?

    
Mitch Wheat 27.01.2010 02:32
quelle