AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wird auf procedure gewartet ?

Ein Thema von Blamaster · begonnen am 22. Okt 2011 · letzter Beitrag vom 23. Okt 2011
Antwort Antwort
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#1

Wird auf procedure gewartet ?

  Alt 22. Okt 2011, 21:45
Delphi-Version: 7
Hi,

folgendes Frage. Mal angenommen ich habe diese for Schleife:

Code:
for i := 1 to 3 do
begin
  SendeDaten(i);
end;
SendeDaten ist dabei eine Procedure geladen aus einer dll.
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#2

AW: Wird auf procedure gewartet ?

  Alt 22. Okt 2011, 22:26
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 Application.ProcessMessages; auf und verarbeitet zwischendurch die anderen anfallenden Messages.


Tipp: Warum hast du es nicht einfach mal selber ausprobiert?
Einfach mehr Schleifendurchläufe ausführen.

Da wir nicht wissen was SendeDaten macht (hat und wieder einmal keiner verraten), können wir keine genaue Antwort geben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (22. Okt 2011 um 22:29 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Wird auf procedure gewartet ?

  Alt 23. Okt 2011, 02:41
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Wird auf procedure gewartet ?

  Alt 23. Okt 2011, 03:51
Ohne mehr Infos zu SendeDaten() kann man nicht mehr sagen.
Nun folgende Frage. Innerhalb der for Schleife wird ja immer solange gewartet bis die procedure SendeDaten fertig ist.
Ohne die procedure SendeDaten zu kennen kann hier nur ein ja kommen.
Denn SendeDaten wird im HauptThread abgearbeitet, und der arbeitet erst weiter, wenn eben 3x SendeDaten durchlaufen wurde.

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

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:
MySendTimer.Enabled := False;
try
  for i := 1 to 3 do
  begin
    SendeDaten( i );
  end;
finally
  MySendTimer.Enabled := True;
end;
Noch besser wäre es, das in einen Thread zu packen:
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;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Wird auf procedure gewartet ?

  Alt 23. Okt 2011, 07:13
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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#6

AW: Wird auf procedure gewartet ?

  Alt 23. Okt 2011, 10:11
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:
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 Ereignisse parallel ablaufen, dann würden Diese zwischen Start und Ende stehen.
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:
    Memo1.Lines.Add('start');
    Sleep(10000);
    Memo1.Lines.Add('ende');
Folgendes ausprobieren.
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');
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (23. Okt 2011 um 10:46 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz