Thema: Delphi Dienst, Sleep oder Timer

Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Dienst, Sleep oder Timer

  Alt 12. Nov 2006, 09:03
Zitat von hoika:
Sollte man dazu Sleep oder einen Timer verwenden ?
Es gab doch mal so ein Problem mit 100% CPU-Auslastung.
Hi,
ich glaube das mit der 100% CPU Last war ein anderes Warten. Mal kurz zur Theorie, wenn du sleep benutzt, dann legst du den aufrufenden Prozess schlafen. Ist dies der Hauptprozess, so reagiert dieser für die Dauer des sleep auf gar nichts mehr. Da werden keine Botschaften entgegen genommen und auf nichts reagiert. Hast du ein normales Programm (mit Fenster), so lässt sich hier kein Element mehr bedienen und kein Formular mehr verschieben oder schließen, bis das sleep verlassen wird.
Eine Alternative dazu bestand immer darin, dass du in einer Schleife wartest. Einfachste Möglichkeit ist es dabei, dass du dir den aktuellen Zeitpunkt t1 nimmst (GetTickCount), in eine leere while Schleife gehst, die erst beendet wird, wenn die nun aktuelle Zeit - t1 größer ist als ein bestimmtes Interval. Das Interval ist dann natürlich deine Wartezeit.
Dabei wird dein Programm diese Schleife aber mit der ihm zur Verfügung stehenden Leistung ausführen, dass können schnell 100% CPU Last sein. Dein Programm bekommt so zwar noch Änderungen mit, allerdings bleibt leider keine Zeit darauf zu reagieren. Der nächste Schritt bestand dann häufig darin, dass man in den Schleifenkörper ein Application.ProcessMessages aufnahm. Das ganze hat dann den Vorteil, dass alle Nachrichten abgearbeitet werden können, die Last der CPU sinkt, Fenster lassen sich verschieben, aber es ist und bleibt einfach Polling. Du schaust (völlig unnötig) ständig nach ob etwas passiert ist (Zeit abgelaufen) und reagierst dann wenn es soweit ist.
Auch dazu gab es dann noch eine Alternative, die um einiges Eleganter vorgeht. Die solltest du per Forensuche nach Delay (evtl. in der Codelib?) finden. Die Idee dort ist es, dass du auf ein bestimmtes Signal wartest. Dies unterstützt Windows direkt. Du kannst dabei auf die Ankunft eines Signals warten. Solange wird dein Prozess schlafen gelegt. Wird das Signal gesetzt, wird dein Prozess wieder aufgeweckt und ihm das Ereignis mitgeteilt. Die entsprechende Windows-Funktion hat aber zwei weitere Abbruchbedingungen. Die eine besteht in einem Timeout. Hier kannst du eine Zeit festlegen, nachder ein Timeout signalisiert wird. Tritt dieses ein, ist der Rückgabewert der Funktion entsprechend. Reagierst du nur auf dieses Signal, hast du einen sehr schönen Timer, der aut. benachrichtigt wird, wenn die Zeit abgelaufen ist. Hier ist kein Polling nötig! Der Prozess wird echt schlafen gelegt (kann z.B. auf Laptops zu einem günstigeren Energiezustand führen). Jetzt bleibt noch das Problem, dass die Fenster verschoben werden könnten, solange der Prozess schläft kann er nicht darauf reagieren. Deswegen ist in dieser Delay-Funktion noch eine weitere Bedingung drin, die den Prozess aufweckt, dass eintreffen von Windows-Botschaften. Auch hier wird der schlafende Prozess geweckt, die Botschaften abgearbeitet und der Prozess für die restliche Zeit (bis zum ursprünglichen Timeout) wieder schlafen gelegt.

Der Unterschied zum Timer besteht in den Lösungen die ich hier bisher erwähnte vorallem darin, dass du direkt an einer Stelle im Code (zwischen zwei Anweisungen) warten kannst. Ein Timer löst eine bestimmte Behandlung aus, wenn sein Interval um ist, möchtest du aber eine bestimmte Zeit zwischen zwei Anweisungen warten, so musst du hier im COde auf diesen Timer synchronisieren. Bei dir sollte das weniger problematisch sein (da kommst du denke ich mit einem Timer aus). Aber ein Timer hat noch einen wichtigen Nachteil, die Genauigkeit. Der Timer läuft nicht mit all zu hoher Priorität. Es kann also bei hoher Last des Systems auch mal dazu kommen, dass das Timer-Ereignis nicht ausgelöst wird. Sollte selten oder nie der Fall sein, kann aber imo passieren (glaube mich zu erinnern, dass es durchaus bei einigen passiert ist).

Gruß Der Unwissende
  Mit Zitat antworten Zitat