Seltsames Programmverhalten einer While - Schleife

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von fliegermichl »

Das Problem ist, daß ShowMessage nicht einfach nur eine Zeile Programmcode ist.
Während ShowMessage läuft, wird weiter der Eventstack der Anwendung mit Events befüllt und diese auch abgearbeitet.
z.B. wird OnActivate des Formulares aufgerufen wenn das ShowMessage Fenster geschlossen wird.
Wenn OnActivate jetzt z.B. Ffufe.ZQueryFundus2.First aufruft, dann hast du den Salat.

Setze einfach in jeder Zeile in deinem Programm, die auf Ffufe.ZQueryFundus2 zugreift einen BreakPoint.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Winni »

Hi!

Meiner Meinung nach löst Du irgenwo im Code mit Deiner Schleife diverse events aus, die Du uns nicht zeigen willst, Bei Showmessage ist nun genug Zeit diese events zu verarbeiten.

Ersetze das Showmessage mit Application.ProcessMesssages. Wenn ich richtig liege, dann sollte es nun funzen. Falls nicht liegt der Fehler in irgendeinem Code, den Du uns nicht zeigen willst.

Winni

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Aliobaba hat geschrieben:
Fr 15. Okt 2021, 09:14
...
Auch ein "Application.ProcessMessages" an diversen Stellen habe ich schon probiert: Nützt nichts.
Den Tip von "siro" werde ich noch probieren und einen "eigenen" ShowMessage-Code basteln.
Ich melde mich dann wieder
... und Danke an Alle hier!!
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von af0815 »

Winni hat geschrieben:
Fr 15. Okt 2021, 16:00
Meiner Meinung nach löst Du irgenwo im Code mit Deiner Schleife diverse events aus, die Du uns nicht zeigen willst, Bei Showmessage ist nun genug Zeit diese events zu verarbeiten.
Auch an die Query gebundene weitere Komponneten (DataSource, visiuelle Komponenten) können aktiv werden, da die Messagequece anläuft und auch der Focus des Fensters sich ändert. Wie Winni sagt, eine MengeRattenschwänze. Nur an welchen hängt die eine gesuchte Ratte :-)

BTW:

Code: Alles auswählen

Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
Würde ich auch nicht mehr trauen, als einem Hütchenspieler. RecordCount kann die je nach Treiber auch nur die Info geben, wieviele Datensätze aktuell gefetched wurden und das müssen nicht alle sein in einem Serversystem.

https://wiki.freepascal.org/SqlDBHowto# ... turn_10.3F

SQLdb und Zeos dürfte da anhand der Meldungen ähnlich sein.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Hallo,
ich habe nun ein Programmverhalten gesehen, das ich mit meinen Kenntnissen nicht näher interpretieren kann, aber vielleicht dem einen oder der anderen von Euch interessant erscheint:

Laienhaft würde ich das so zusammen fassen:
Diese "While-Schleife" mag keine Pausen, wenn mit Datenbankeinträgen gearbeitet wird..

Code: Alles auswählen

Procedure Testtest;
var
  sss , kkk :string;
  n  : integer;
begin
 n := 0 ;
 kkk := '';
 Ffufe.ZQueryFundus2.First;
 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
 while not Ffufe.ZQueryFundus2.EOF do
 begin
   n:= n+1;
   sss := Ffufe.ZQueryFundus2.FieldByName('CPfadG').AsString ;
   kkk := kkk + LineEnding + sss ;

   Form_Start.Ed_ZeigMess.Text:= sss ;  // Edit Feld
   Application.ProcessMessages;
   sleep(100);

   Ffufe.ZQueryFundus2.Next;
 end;
 Showmessage('Ende: '+ inttostr(n) + ': ' + kkk);
end; 

Meine Probe-Datenbank enthält nun 6 Einträge/Zeilen

Das Programm läuft dann durch (=erreicht die ShowMessage "Ende..."), wenn der sleep-Befehl auskommentiert ist oder sehr kleine Zeiten enthält ( kleiner als ca. 5 msec).

Bei einem mittleren Zeitbereich von ca. 10-30 msec kommt das Programm ebenfalls zu einem Ende, aber mit einer seltsamen Ausgabe der ShowMessage "Ende...": Es werden dann 3-4 mal hintereinander (nicht jedesmal exakt identisch reproduzierbar) nur die ersten 3-4 Datenbank-Zeilen angezeigt, aber diese 3-4 Zeilen wenige male wiederholt ausgegeben (obwohl die DB eigentlich 6 Zeilen enthält)

Bei großen Werten in "sleep" (z.B. 100msec) erreicht die Schleife das Ende nicht. Das gesamte Programm friert dann auch ein und reagiert nicht mehr.

Ich interpretiere das so:
Wenn in dieser Schleife eine Pause auftritt, dann vermutet das Programm einen Fehler und der Schleifenzähler ("n") beginnt von vorne. Bei kleinen sleep-Werten "kommt er nicht weit", eben nur die oben genannten 3-4 Programmzeilen und beginnt dann von vorne. Irgendwann springt das Programm dann doch an das Ende und zeigt diese Zeilen-Wiederholungen in der ShowMessage "Ende..." an. Bei großen Sleep-Werten führen diese Wiederholugen, bzw. Neustarts der Schleife dann zu einem Absturz(?) und die Schleife wird nicht mehr beendet.

Und noch etwas: Die Anzeige im Edit Feld "Ed_ZeigMess.Text" wird in keinem der genannten Fälle aktualisiert, auch nicht durch das "Application.ProcessMessages".

Ach ja - - und dieser Code funktioniert problemlos.
Zusammenhang mit dem Inhalt in der Zeile "While not..." ? -> Fehler tritt also nur auf, wenn Datenbankzeilen der Reihe nach aufgerufen werden.

Code: Alles auswählen

Procedure Testtest_5;
var
  n  : integer;
begin
 n := 0 ;
 while not (n>5)   do
 begin
   n:= n+1;
   Form_Start.Ed_ZeigMess.Text:= inttostr(n) ;   // Edit Feld
   Application.ProcessMessages;  // Anzeige nur mit dieser Programmzeile
   sleep(500);
 end;
 Showmessage('Ende: '+ inttostr(n) );
end;   
Das alles sind nun nur zusammen getragene "Symptome". Eine Diagnose kann ich mit meinen Kenntnissen natürlich nicht stellen.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von af0815 »

Ohne Demo Programm wird es ein lesen der trüben Glaskugel bleiben.

Ich arbeite täglich mit Datenbanken und Lazarus beruflich. Hätte ich die Probleme so wäre ich reif für die Insel.

Du kannst nur versuchen die Problemstellung in einem Demoprg unter zu bringen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von wp_xyz »

Genau. Die ganzen Code-Schnipsel und Experimente sind wertlos für uns, weil wir es nicht nachvollziehen können und weil wir nicht wissen was außerhalb dieser paar Zeilen sonst noch passiert. Wir wissen noch nicht einmal, um welche Datenbank es sich handelt.

Bitte nimm dir die Zeit, und schreibe ein kleines Demo-Programm und lade es hoch, dann kann jeder des Problem nachvollziehen.

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Hallo und Guten Morgen,

mir ist schon klar, dass eine Fehlersuche auf diese Weise nicht möglich ist und auch eine Zumutung an die, von denen man das erwartet. Um bei meinem Bild zu bleiben: Auch ein Arzt kann per Internet keine vernünftige Diagnose stellen; man muss den Patienten persönlich sehen und ihm gegenüber sitzen!
Und ich erwarte natürlich auch nicht, dass ihr viel Zeit aufwendet, um den Fehler zu suchen. Aber es hätte ja sein können, dass jemand spontan sagt: "Ach ja, das Problem kenne ich! Ganz einfach! Liegt an ..."
Ein Excerpt aus meinem Programm zu erstellen ist für mich alles andere als trivial und wahrscheinlich nützt es auch nichts, denn man braucht den gesamten Programmcode.
Diesen Code kann ich aber aktuell beim besten Willen niemandem zumuten; nicht weil ich nicht möchte, sondern weil die Software ( https://www.heise.de/download/product/myplaylist )aktuell massiv im Umbau ist und aktuell noch ein wirkliches Chaos! Sobald man sich mit der Software wieder "einigermaßen sehen lassen kann" schicke ich den Quellcode gern an den, der sich dafür interessiert, insbesondere an af0815, wp_xyz, Winni, fliegermichl, charlytango und siro.

Bei Euch bedanke ich mich sehr für Eure Hilfsbereitschaft.

Einstweilen kann ich ja mit dem Problem leben; ich mache halt keine Pause in der Schleife und alles funktioniert wunderbar.

Schönes Wochenende!
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von af0815 »

Einen Vorschlag gibt es noch. Setze nochmals eine neue Query auf das Formular/Datenmodul wo die andere Query ist. Parametrier sie gleich, ohne sie mit einem Datenset zu verbinden. Verschwindet, so könnte es ein Seiteneffekt aus einem Ereignis bei der originalen Komponente sein. Läuft es ohne Probleme, so könntest du die angehängten Datensets 'umhängen' und wieder testen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Epcop
Beiträge: 140
Registriert: Di 29. Mai 2012, 09:36

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Epcop »

Ich habe nicht den ganzen Thread durchgelesen.

Ohne zu testen, vermute ich hier den Fehler:

Code: Alles auswählen

 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
 while not Ffufe.ZQueryFundus2.EOF do

Ich weiß nicht was Ffufe.ZQueryFundus2.EOF macht. Warum nicht das in der vorherigen Showmessage() verwenden?

Code: Alles auswählen


 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
   For n := 0 to Ffufe.ZQueryFundus2.RecordCount-1 do // n willst du ohnehin zählen!?
   
 

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von af0815 »

Epcop hat geschrieben:
So 17. Okt 2021, 20:12
Ich weiß nicht was Ffufe.ZQueryFundus2.EOF macht. Warum nicht das in der vorherigen Showmessage() verwenden?

Code: Alles auswählen

 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
   For n := 0 to Ffufe.ZQueryFundus2.RecordCount-1 do // n willst du ohnehin zählen!?
    
Verwende RecordCount NIE für solche Zwecke, das mit EOF ist schon die korrekte Methode. Zu dem Thema RecordCount habe ich ein paar Posts vorher schon was geschrieben.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Hallo @ af0815
Danke für Deine geduldige Hilfsbereitschaft!

Ich habe versucht, Deine Hilfestellungen zu bearbeiten.
Vorweg: Die ZConnection ist auf einem anderen Formular als die TZQuerrys und die DataSources. Das ist "historisch" bedingt, gab aber nie Probleme.
Ich habe nun eine neue Query erstellt auf der gleichen Form wie die ZConnection. Ohne zugehörige Datasource ging das nicht zu starten, also habe ich auch eine weitere Datasource auf die Form gezogen und mit den nötigen Parametern eingebunden (ist das "parametrieren"? Sorry, bin wirklich nicht tief in dieser Materie). Die Variablen in der Procedure habe ich entsprechend auf die neue Datasource und Query umgeschrieben.
Auch das funktionierte nicht; wahrscheinlich ist da noch viel mehr anzupassen, was ich aber nicht kann, da mir diese Kenntnisse schlicht fehlen.
Also habe ich die neue Query und die neue Datasource wieder von der Form entfernt und auch die Procedure entfernt, die dieses "Pausen-Problem" macht. Und dann ging plötzlich das gesamte Programm nicht mehr :( (Sogar mit Debugger-Absturz!?)
Nach vielen Probieren schaffte ich es dann doch endlich, das Programm wieder zum Laufen zu bringen.

Und da bin ich jetzt richtig froh!

Seid mir bitte nicht böse. Mir fehlen einfach schlichte Grundkenntnisse im Umgang mit Datenbanken und wohl auch im Umgang mit Lazarus. Umso mehr gilt für mich: Never touch a running system!
Und jetzt läuft's wieder und ich rühre das Ding nicht mehr an!
Die Procedure, die Probleme macht, wenn darin Pausen gemacht werden (Sleep oder ShowMessage), funktioniert ja, wenn man solche Pausen nicht einbaut, warum auch immer. Und damit muss ich nun einfach zufrieden sein, auch wenn ich nicht erfahren werde, warum das so ist.

Wie schon gesagt, ich möchte sicher nicht Eure Zeit zu sehr in Anspruch nehmen; denn wie ich schon sagte: es hätte ja sein können, dass jemand ganz spontan sofort eine Lösung kennt.

Nochmal: Vielen Dank und eine schöne Woche!
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von af0815 »

Dann würde ich dir vorschlagen, die Finger von ShowMessage zu lassen und es mit DebugLn zu probieren. Das ist dann am wenigsten invarsiv.

Allgemein zu betrachtet, würde ich mir schon langfristig Gedanken zu dem Thema Datenbanken und defensive Programmierung machen :-)

Aus meiner jahrelangen Erfahrung kann ich sagen - das holt dich ein, wenn du es am wenigsten brauchst oder vermutet. :mrgreen:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten