Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Application.processmessages bremst Programm unter Windows 7 aus (https://www.delphipraxis.net/193523-application-processmessages-bremst-programm-unter-windows-7-aus.html)

v2afrank 10. Aug 2017 06:23

Delphi-Version: 6

Application.processmessages bremst Programm unter Windows 7 aus
 
Hallo,
ich habe hier ein Programm von 2003 vorliegen mit dem wir unsere Hardware seriell Flashen. Der Kollege der das damals geschrieben hat ist leider nicht mehr greifbar, und ich scheue mich davor große Änderungen an diesem Programm vorzunehmen.
Das Problem ist folgendes. Das Programm läuft schon jahrelang gut auf unseren Prüffeldrechnern. Das Flashen dauerte dabei pro Prüfling ca 30 Sekunden. Nun wurden die Rechner von Xp auf Windows 7 umgestellt. Dadurch ist die Zeit auf ca 300 Sekunden angestiegen. Wir hatten zuerst irgend einen Virenscanner in Verdacht, aber das war es auch nicht, so dass ich um Hilfe gebeten wurde. Auf meinem System kann ich es auch nachvollziehen allerdings nicht so extrem. Auf meinem XP (eine virtuelle Maschine auf der auch Delphi 6) läuft brauche ich 43 Sekunden, auf dem Hostrechner (Windows 7 64Bit) 65Sekunden.
Ich habe es jetzt so weit runterbrechen können, dass ich folgende Routine als Übeltäter ausgemacht habe
Delphi-Quellcode:
procedure TLegacySerialProgrammerModule.ComPortAdapterSendChar(
  Sender: TObject; const Value: Char; const ContentType: TContentType);
begin
  while ComPort1.OutBuffUsed>0 do
      application.ProcessMessages;
  if ComPort1.Open then
  begin
    ComPort1.PutChar(Value);
  end;
end;
Comport1 ist dabei vom Typ TApdComPort aus der Turbopower Sammlung. Falls nötig kann ich die genaue Version raussuchen.
Warum auch immer wird hier also jedes Zeichen einzeln gesendet und dabei zuerst nachgeschaut ob der Outputbuffer des Comports schon leer ist. Dies ist genau das Problem. Nehme ich das Application.processmessages oder die gesamte Abfrage while ComPort1.OutBuffUsed>0 raus läuft das Programm auch unter Windows 7 genauso schnell wie unter Windows XP. Allerdings kommt es immer mal wieder zu einem Kommunikationsfehler den das Programm auch erkennt wodurch der ganze Flashvorgang schief läuft.
Normalerweise würde ich jetzt hingehen und das Programm umschreiben, aber wie gesagt das ist so umfangreich und ich blicke da selber noch nicht ganz durch, so dass ich Angst habe etwas zu verschlimmbessern.
Lange Rede kurzer Sinn. Hat noch einer von Euch eine Idee wie ich hier einfach etwas umstellen kann ?

bra 10. Aug 2017 08:57

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Vielleicht könnte man statt oder zusätzlich zu dem Application.ProcessMessages noch ein Sleep(xx) (z.B. 100) mit einbauen? Das könnte aber an anderer Stelle zu Hängern führen, wenn das in einem Thread läuft o.ä.?

Aviator 10. Aug 2017 09:03

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Eigentlich sollte eine Sende-Methode die länger als ein paar Milisekunden dauert in einen eigenen Thread ausgelagert werden. Dann würde nämlich auch das
Delphi-Quellcode:
Application.ProcessMessages
wegfallen, da nicht mehr benötigt.

Das wäre dann allerdings eine größere Änderung die Du dir, wie du selbst schreibst, ja nicht zutraust. Ich gebe zu, dass es teilweise schwierig ist, sich in ein fremdes Programm einzuarbeiten. Aber vielleicht könntest Du das ja mal ausprobieren. Mach Dir eine Sicherheitskopie des Projektes, eine SourceCode Verwaltung wurde wahrscheinlich ja nicht genutzt, und fang dann an, die Sende Methoden in einen Thread auszulagern. Wenn das dann funktioniert, dann kannst Du ja evtl. auch die Art des Sendens versuchen zu verbessern und damit vielleicht einen Geschwindigkeitsvorteil erzielen.

Wie groß sind denn die Daten die geflasht werden und mit welcher Baud-Rate wird gesendet? Kommt das rein rechnerisch mit über 30 Sekunden überhaupt hin? Falls ja, dann kannst Du da auch nichts mehr optimieren. Falls es rein rechnerisch viel schneller gehen müsste, kannst Du ja versuchen zu optimieren.

PS: Alleine dieser kleine Ausschnitt hilft uns natürlich auch nicht viel weiter um Dir da angemessen helfen zu können. Ich habe nur die Befürchtung, dass das Programm überall etwas von hinten durch die Brust ins Auge geschrieben ist. :wink:

Ydobon 10. Aug 2017 09:22

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Liegt es denn tatsächlich an dem ProcessMessages? Beim Umstieg auf Win 7 könnte man auch auf Hardware-/Treiberprobleme tippen und ein langsameres Reagieren des ComPorts. Wie oft wird die Schleife denn jeweils durchlaufen?

v2afrank 10. Aug 2017 09:40

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Wie gesagt es liegt an dem Processmessages. Lasse ich es weg komme ich auch unter Windows 7 zu den gut 30 Sekunden. Ein Sleep habe ich Testweise auch eingebaut, funktioniert dann auch, dauert aber dann eben auch länger.
Das Projekt ist natürlich in einem Sourcecodecontrolsystem, so dass Änderungen durchaus möglich wären. Mir ist schon klar dass dieser kleine Ausschnitt nicht viel weiter hilft, aber das ist wirklich der unterste Teil der zu dem Problem führt.
Die 30 Sekunden kommen rechnerisch auch sehr gut hin, aber nicht die 300 die jetzt unter Windows 7 auftauchen.
Wie oft die Schleife denn so durchlaufen wird habe ich noch nicht zählen lassen. Kann ich aber gerne noch machen.

nahpets 10. Aug 2017 11:41

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Eine Schleife mit permanentem ProcessMessage führt auch unter XP zu Verzögerungen, nur anscheinend nicht so massiv. Kenne das von Delphi 7.

Wenn ich so eine Schleife machen muss, dann kommt da immer auch ein Sleep rein, welche Wartezeit im Sleep steht, ist dann immer etwas von der zu erledigenden Aufgabe abhängig.

Wie bra schon schrieb, bitte mindestens in sowas der Art abändern:
Delphi-Quellcode:
procedure TLegacySerialProgrammerModule.ComPortAdapterSendChar(
  Sender: TObject; const Value: Char; const ContentType: TContentType);
begin
  while ComPort1.OutBuffUsed>0 do
  begin
    // Hier prüfen, ob es ruhig etwas länger
    // als 20 Millisekunden sein darf,
    // Tendenz eher in Richtung höher Wartezeit.
    Sleep(20);
    application.ProcessMessages;
  end;
  if ComPort1.Open then
  begin
    ComPort1.PutChar(Value);
  end;
end;
Aus einem meiner Programme weiß ich, dass mit Delphi 7 unter XP eine Schleife mit einem Sleep unter 20 Millisekunden, auf 'nem recht alten Rechner, zu einem massiven Anstieg der CPU-Last führt, man beschäftigt so Windows ausschließlich mit der Verarbeitung der Messages. Aber ein sinnvolles aktives Warten kann man so nicht wirklich realisieren.

Optimal ist so eine Lösung nicht, aber zumindest mit 'nem überschaubaren Aufwand zu realisieren. Ihr müsstest aber gründlich testen, mit welcher Wartezeit ihr hier arbeiten könnt, damit keine anderen Nebenwirkungen auftreten.

v2afrank 10. Aug 2017 11:51

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Ja danke, hatte ich auch schon so verstanden. Problem ist aber dass es eher umgekehrt ist. Wenn ich ein Sleep dahin mache wird die Zeit auch unter XP deutlich höher. (Ob 7 kann ich jetzt nicht sagen da nicht getestet)
Vermutlich wird die Schleife bei beinahe jedem Zeichen angesprungen.
Interessant finde ich aber Deine Aussage dass Du das auch von Delphi 7 kennst.

Glados 10. Aug 2017 12:02

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Vielleicht könnte man statt oder zusätzlich zu dem Application.ProcessMessages noch ein Sleep(xx) (z.B. 100)
Dann würde bei der Übermittlung von nur 40 Buchstaben das Programm schon länger arbeiten, als es ohnehin schon unter Windows 7 tut :P

Ydobon 10. Aug 2017 12:19

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
ProcessMessages räumt doch lediglich die Botschaftswarteschlange leer, damit die Anwendung während langer Schleifen nicht einfriert, was Sleep z.B. macht. Eine Verlängerung der Zeit sollte dann höchstens auftreten, wenn die Computerlast dadurch zu hoch und anderen Prozessen Zeit entzogen wird. Wenn es wirklich daran liegt, wäre HandleMessage vielleicht eine Idee oder eine Schleife ohne ProcessMessage, die aber vermutlich für hohe Last und weitere Probleme sorgen könnte.
Delphi-Quellcode:
while true do
begin
  if ComPort1.OutBuffUsed=0 then break;
end;

freimatz 10. Aug 2017 12:23

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Nu so ins Blaue: warum nicht "while ComPort1.OutBuffUsed>1 do"?
Dann kann der Buffer nicht überlaufen, aber es ist immer noch ein Zeichen in Reserve zum Schreiben noch da.

v2afrank 10. Aug 2017 12:48

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Der Schuss ins Blaue hat tatsächlich geholfen. Ich habe daraus ein >10 gemacht und jetzt funktioniert es auch unter 7.
Die Frage wäre natürlich was macht das Processmessages da wirklich unter 7. Aber ob man das herausfinden kann ?

Danke Euch allen erst einmal

p80286 10. Aug 2017 14:44

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Delphi-Quellcode:
procedure TLegacySerialProgrammerModule.ComPortAdapterSendChar(
   Sender: TObject; const Value: Char; const ContentType: TContentType);
begin
   while ComPort1.OutBuffUsed>0 do
       application.ProcessMessages;
   if ComPort1.Open then
   begin
     ComPort1.PutChar(Value);
   end;
end;
Das erinnert mich doch sehr an DOS-Zeiten
Delphi-Quellcode:
...
while BufferI<>Bufferlast do begin write('.') end;
writeln;
TuWas_mit_Buffer;
...
nur wird hier nichts ausgegeben, darum weißt Du nicht wieviel Zeit das Programm in der Warteschleife verbringt.

Übrigens, ist Value wirklich ein Char oder doch ein AnsiChar?

Gruß
K-H

v2afrank 11. Aug 2017 06:10

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Wirklich ein Char.
Bitte nicht vergessen. Das Programm ist gut 15 Jahre alt.

TigerLilly 11. Aug 2017 13:29

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Lass das Application.ProcessMessages mal weg. Damit wird die App zwar "reagiert nicht", aber das kann hier kein langer Zeitraum sein.

p80286 11. Aug 2017 21:31

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Zitat von v2afrank (Beitrag 1378547)
Wirklich ein Char.
Bitte nicht vergessen. Das Programm ist gut 15 Jahre alt.

Eben drum unter XE2 sollte der "alte" char dem AnsiChar entsprechen, und da ich davon ausgehe, daß es sich um binäre Daten handelt, wäre ein Byte wohl besser.

Gruß K-H

t.roller 11. Aug 2017 21:53

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Test:
Delphi-Quellcode:
procedure TLegacySerialProgrammerModule.ComPortAdapterSendChar(
   Sender: TObject; const Value: Char; const ContentType: TContentType);
begin
   while ComPort1.OutBuffUsed>0 do
BEGIN
Label1.Caption:= FormatDateTime('hh:nn:ss:zzz', Time);
       application.ProcessMessages;
Label2.Caption:= FormatDateTime('hh:nn:ss:zzz', Time);
END;
   if ComPort1.Open then
   begin
     ComPort1.PutChar(Value);
   end;
end;
Die Differenz zwischen VOR "application.ProcessMessages;" und NACH sollte nicht grösser als 1 - 2 msec sein.
Man kann dann testen, ob ein Einfügen von "Sleep(1)" eine grosse Differenz auf ca. 3 msec verkleinert.

himitsu 11. Aug 2017 22:29

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Zitat von t.roller (Beitrag 1378625)
Die Differenz zwischen VOR "application.ProcessMessages;" und NACH sollte nicht grösser als 1 - 2 msec sein.

Leg dir einen Timer mit Sleep(1000) auf die Form und ich wette deine Aussage stimmt nicht.

Application.ProcessMessages hat eben gerade das "Problem", dass man nicht weiß was darin alles für Messages verarbeitet werden und Wieviele, also kann auch niemand mit Sicherheit sagen wie lange es dauert und was es für Auswirkungen hat.

z.B. kann dadurch ein Button doppelt geklickt werden und im zweiten durchgang, mitten innerhalb des ersten Aufrufs, kann sonstwas schief gehn, wenn in dem Button auf globale Variablen zugegriffen wird.

jaenicke 12. Aug 2017 14:13

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Zitat von TigerLilly (Beitrag 1378601)
Lass das Application.ProcessMessages mal weg. Damit wird die App zwar "reagiert nicht", aber das kann hier kein langer Zeitraum sein.

Der Comport funktioniert über Messages. Es kann sein, dass ohne die Verarbeitung der Messages gar nichts passiert. Das mussten wir auch schon einmal feststellen.

hzzm 22. Aug 2017 13:04

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Zitat von v2afrank (Beitrag 1378473)
so dass ich Angst habe etwas zu verschlimmbessern.

Ich denke nur, dass es heutzutage gar nicht mehr angebracht ist, auch nur irgendein programmmier-Projekt ohne Git in die Hand zu nehmen.

Selbst wenn ich fuer mich selber, wissend, dass nie ein zweiter Mensch Hand am Code anlegt, fuer mich im Kaemmerchen privat programmiere;
Selbst wenn ich 100%ig weiss, dass es nur eine einzige Version dieser Software geben wird;
Selbst wenn ich ein riesen Projekt in die Hand kriege, mit dem ich noch nie etwas zu tun gehabt habe, das keine Versionskontrolle nutzt.

TortoiseGit -> Rechtsklick -> Create repository here.
Keine Zeile Code ohne Git. Damit gehoert es zur Vergangenheit, irgendetwas versehentlich kaputt zu reparieren.
Versionsverwaltung ist seit 35 Jahren absoluter Standard, aus gutem Grund.


Dann ab ins kalte Wasser und Verbindungs-Krempel immer Threaded laufen lassen.

v2afrank 22. Aug 2017 13:27

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Ich weiß nicht wie das Gerücht aufgekommen ist. Selbstverständlich benutzen wir ein VCS . Nur eben nicht Git sondern PTC.
Das Trauen bezog sich eher darauf dass ich mir nicht sicher bin ob ich alles überblicke was die Software macht. Ich denke ich würde es auch threaded hinbekommen aber ob ich alle Konstellationen erwische ?

hzzm 22. Aug 2017 13:51

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Zitat:

Zitat von v2afrank (Beitrag 1379198)
Selbstverständlich benutzen wir ein VCS .

Achso, sorry. Das hab' ich dann fehlinterpretiert.

Luckie 23. Aug 2017 21:01

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Die Angst kenne ich. Da dreht man etwas an dem Schräubchen und an dem anderen Schräubchen am Kleiderschrank im Schlafzimmer und plötzlich fällt der Küchenschrank runter. :mrgreen: Ist-Zustand ins Repository und dann an den Schräubchen drehen.

freimatz 24. Aug 2017 12:49

AW: Application.processmessages bremst Programm unter Windows 7 aus
 
Dagegen hilft z.B.:
https://en.wikipedia.org/wiki/Single...lity_principle


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 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