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:
Comport1 ist dabei vom Typ TApdComPort aus der Turbopower Sammlung. Falls nötig kann ich die genaue Version raussuchen.
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; 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 ? |
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.ä.?
|
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:
wegfallen, da nicht mehr benötigt.
Application.ProcessMessages
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: |
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?
|
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. |
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:
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.
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; 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. |
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. |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
|
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; |
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. |
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 |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Delphi-Quellcode:
Das erinnert mich doch sehr an DOS-Zeiten
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;
Delphi-Quellcode:
nur wird hier nichts ausgegeben, darum weißt Du nicht wieviel Zeit das Programm in der Warteschleife verbringt.
...
while BufferI<>Bufferlast do begin write('.') end; writeln; TuWas_mit_Buffer; ... Übrigens, ist Value wirklich ein Char oder doch ein AnsiChar? Gruß K-H |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Wirklich ein Char.
Bitte nicht vergessen. Das Programm ist gut 15 Jahre alt. |
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.
|
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
Gruß K-H |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Test:
Delphi-Quellcode:
Die Differenz zwischen VOR "application.ProcessMessages;" und NACH sollte nicht grösser als 1 - 2 msec sein.
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; Man kann dann testen, ob ein Einfügen von "Sleep(1)" eine grosse Differenz auf ca. 3 msec verkleinert. |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
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. |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
|
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
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. |
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 ? |
AW: Application.processmessages bremst Programm unter Windows 7 aus
Zitat:
|
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.
|
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