![]() |
Delphi-Version: 7
Wird auf procedure gewartet ?
Hi,
folgendes Frage. Mal angenommen ich habe diese for Schleife:
Code:
SendeDaten ist dabei eine Procedure geladen aus einer dll.
for i := 1 to 3 do
begin SendeDaten(i); end; Die schleife selber steckt im OnTimer Event eines Timers mit einem 20ms Intervall. Nun folgende Frage. Innerhalb der for Schleife wird ja immer solange gewartet bis die procedure SendeDaten fertig ist. Was würde jetzt passieren, wenn der in der procedure abzufertigende Code länger dauert als die 20ms vom Timerintervall ? Gruß Yannic |
AW: Wird auf procedure gewartet ?
Der Timer läuft über Messages innerhalb des Hauptthreads (der VCL) und in einem Thread kann natürlich immer nur einwas gleichzeitig abgearbeitet werden.
Also ja, es wird gewartet. (vermutlich) Ausnahme: Man/Etwas ruft irgendwo
Delphi-Quellcode:
auf und verarbeitet zwischendurch die anderen anfallenden Messages.
Application.ProcessMessages;
Tipp: Warum hast du es nicht einfach mal selber ausprobiert? Einfach mehr Schleifendurchläufe ausführen. :roll: Da wir nicht wissen was SendeDaten macht (hat und wieder einmal keiner verraten), können wir keine genaue Antwort geben. |
AW: Wird auf procedure gewartet ?
Ad 1: Es kommt auf die Implementierung von SendeDaten() an. Wird dort ein Workerthread pro Aufruf mit dem eigentlichen Senden beauftragt, wird nicht zwangsweise bis zum tatsächlichen Abschluss des Sendens gewartet. (Synchron versus Asynchron, um mal Schlagworte zu liefern)
Ad 2: Trifft ein Timer-Event (bzw. irgendein Event) ein, während der Verarbeiter (dein Formular z.B.) beschäftigt ist, kommt er in eine Warteschlange. Die nimmt imho aber auch nur begrenzt Messages auf (Message-Queue heisst das Teil), wonach die Events verworfen werden. Deine Timer-Prozedur wird nicht mehrfach parallel aufgerufen, aber deine 20ms sind in Gefahr (welche ohnehin schon nah der Untergrenze der Schnelligkeit von Timern sind, wodurch die ohnehin schon recht fragwürdig sind). Fazit: Ohne mehr Infos zu SendeDaten() kann man nicht mehr sagen. |
AW: Wird auf procedure gewartet ?
Zitat:
Zitat:
Delphi-Quellcode:
zu kennen kann hier nur ein ja kommen.
procedure SendeDaten
Denn
Delphi-Quellcode:
wird im HauptThread abgearbeitet, und der arbeitet erst weiter, wenn eben 3x
SendeDaten
Delphi-Quellcode:
durchlaufen wurde.
SendeDaten
Ich bin aber völlig bei dir, dass ein Timer mit 20ms mehr als fragwürdig ist ;) Vor allem weil die Gefahr besteht, dass der Timer die Warteschlange so vollmüllen wird, dass die Anwendung einfach immer nur das TimerEvent aufrufen wird :mrgreen: Ein mögliche (nicht schöne aber besser laufende) Lösung ist den Timer für die Dauer der Verarbeitung ausser Gefecht zu setzen
Delphi-Quellcode:
Noch besser wäre es, das in einen Thread zu packen:
MySendTimer.Enabled := False;
try for i := 1 to 3 do begin SendeDaten( i ); end; finally MySendTimer.Enabled := True; end;
Delphi-Quellcode:
procedure TMySendThread.Execute;
begin while not Terminated do begin for i := 1 to 3 do begin SendeDaten( i ); end; if not Terminated then // wirklich schlafen wird der nicht ;o) // aber er ist halt stets bemüht Sleep( 20 ); end; end; |
AW: Wird auf procedure gewartet ?
Der Timer generiert alle 20 ms eine Message, die auch abgearbeitet werden will.
Also 500 Schleifenaufrufe pro sec. Da wird nichts vergessen oder uberholt oder ... Worauf willst Du denn hinaus? Ich habe den Eindruck, Du bist auf dem besten weg Dir selbst ein Beinzu stellen. Gruß K-H |
AW: Wird auf procedure gewartet ?
Timer-Messages sind niederwertig und ich glaub es ist immer nur maximal Eine in der MessageQueue vorhanden ... ist also die selbe Message schonmal drin, wird keine Neue eingetragen.
Bei Start der Ausführung des Timer-Ereignisses wird die aktuelle Message aus der Queue abgefrag und gelöscht. Wärend der abarbeitung fällt also maximal nur eine weitere Message an, welche auf die nächste Bearbeitung wartet. [add] Einen Timer mit einem Intervall von 100 ms.
Delphi-Quellcode:
Würden Ereignisse parallel ablaufen, dann würden Diese zwischen Start und Ende stehen.
var
TimerStart, LastTimer, TimerCalls: Cardinal; procedure TForm8.Timer1Timer(Sender: TObject); begin if TimerStart = 0 then begin TimerStart := GetTickCount; LastTimer := TimerStart; end; Inc(TimerCalls); mnQueryText.Lines.Add(Format('%d %.2n %.2n', [TimerCalls, (GetTickCount - TimerStart) / 1000, (GetTickCount - LastTimer) / 1000])); LastTimer := GetTickCount; if TimerCalls = 100 then begin mnQueryText.Lines.Add('start'); Sleep(10000); mnQueryText.Lines.Add('ende'); end; if TimerCalls = 300 then Timer1.Enabled := False; end; Würden sich Ereignisse ansammeln/aufhäufen, dann würden nach dem Ende 100 Einträge (Pause durch Intervall) ganz schnell auftachen, da sie alle abgearbeitet würden. Und zugleich sieht man, daß diese Timer relativ ungenau sind, denn die Zeit läuft dem Zähler voraus, da der Zähler der Zeitanzeige hinterherläuft. Würde es synchron/genau laufen, wäre ja die Zeit immer etwa ein Zehntel des Zählers. Alternativ mal statt
Delphi-Quellcode:
Folgendes ausprobieren.
Memo1.Lines.Add('start');
Sleep(10000); Memo1.Lines.Add('ende');
Delphi-Quellcode:
Memo1.Lines.Add('start');
for i := 1 to 200 do begin // 200 * 50 = 10000 Sleep(50); Application.ProcessMessages; end; Memo1.Lines.Add('ende'); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz