none
Timer aus unterschiedlichen Threads starten/stoppen RRS feed

  • Frage

  • Hallo,

    ich habe einen Service der anhand einer Liste nacheinander WMI-Kommmandos absetzt, die dann zeitverzögert einen weiteren Service - nennen wir ihn WorkService - triggert.  Nach jedem Kommando soll so lange gewartet werden, bis der WorkService seine Ausführung beendet hat bevor das nächste Kommando abgesetzt wird. Zum Warten wird ein Timer gestartet, der alle 60 Sekunden den Status des WorkServices prüft und ggf. das nächste Kommando startet oder weiter wartet. Über einen ManagementEventWatcher erhält mein Service darüber hinaus Statusmeldungen des WorkService die u.a. für's Logging und auch zur Steuerung verwendet werden.

    Wenn ein Event ausgelöst wird müssen zunächst diverse WMI abfragen ausgeführt werden, was u.U. zu einer Verzögerung führen kann. Um zu verhindern, dass just zu diesem Zeitpunkt das Timerinterval abläuft, wir am Anfang der Eventhandlermethode der Timer gestoppt und am Ende ggf. wieder gestartet. Da der Eventhandler aus den verschiedenen Threads des Workservices aufgerufen wird kann es nun vorkommen, dass zunächst Timer.Start aus Thread 2 ausgeführt wird, dann aber durch den Aufruf des Eventhandlers, der im Thread 4 läuft, Timer.Stop ausgeführt wird. Dies führt aber dazu, dass der Timer aus Thread 2 nicht beendet wurde.

    Wie kann ich nun sicherstellen, dass immer der Timer aus dem selben Thread gestartet/gestoppt wird bzw. wie kann ich den Timer eines bestimmten Threads starten/stoppen.

    Vielen Dank im Vorraus

     

    Dienstag, 30. August 2011 15:38

Antworten

Alle Antworten

  • Hallo,

    es mag an der frühen Stunde liegen, aber so ganz verstehe ich nicht, wozu Du mehrere Timer bemühst.

    Zum einen sollte in einem Service ein System.Threading.Timer verwendet werden, und der läuft wiederum auf einem eigenen (Worker)-Thread.
    siehe Comparing the Timer Classes in the .NET Framework Class Library
    und http://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer

    Die Timer (Ereignisse) wären insofern schon mal nicht wirklich thread-spezifisch.

    Um den Zugriffe auf eine Instanz (hier Timer) zu synchronieren, reicht prinzipiell ein lock / SyncLock.

    Bei mehreren Instanzen, die sich wiederum in mehreren Threads tummeln,
    bekommt  man aber über kurz oder lang in einen Deadlock oder in eine Race Condition,
    siehe Empfohlene Vorgehensweise für das verwaltete Threading

    Anstatt die Timer zu stoppen, wäre ein günstigeres Vorgehen, einen Arbeitsauftrag in eine Queue zu stellen
    Mit .NET 4.0 in eine BlockingCollection (oder bei NET 2/3.5 eine blockierende Queue wie sie Stephen Toub zeigt).

    Um die Threads "vom Überholen" abzuhalten, wären EventWaitHandle geignet
    (bei .NET 3.5 ein ManualResetEvent oder mit .NET 4 auch ein CountDownEvent).

    Gruß Elmar

    Dienstag, 30. August 2011 23:26
    Beantworter
  • Elamr hat recht. Ich würde komplett auf den Timer verzichten und die Threads mittels Events synchronisieren.
    Auch solltest du dir die ThreadPool-Klasse ansehen. Auch Work Queue based multi-threading ist fürs Verständnis sehr hilfreich.

    Mittwoch, 31. August 2011 08:51
  • Hallo Elmar,

    danke für deine Antwort.

    In meinem Service gibt es nur einen Timer und einen ManagementEventWatcher. Da der WorkerService von einem externen Hersteller ist habe ich keinen Einfluss auf die Events , die ich über den ManagementEventWatcher abfangen kann. Da diese Leider nicht 100%ig zuverlässig ausgelöst werden, benötige ich zusätzlich einen Timer der periodisch nachschaut ob der WorkService fertig ist.

    Ich werde aber zunächst mal deinen Rat befolgen und auf den System.Threading.Timer umstellen die verlinkten Infos durchlesen und dann wieder melden.

    Gruß

    DevBiker01

     

    Mittwoch, 31. August 2011 09:34
  • Hallo Stefan,

    dnake für deine Antwort. Werde mir die Lektüre mal vornehen.

    Gruß

    DevBiker01

     

    Mittwoch, 31. August 2011 09:35
  • Hallo DevBiker01,

    Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Donnerstag, 8. September 2011 06:35
    Moderator