Seltsames Programmverhalten einer While - Schleife

Für Fragen von Einsteigern und Programmieranfängern...
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Hallo,

ich stolperte über ein eigenartiges Programmverhalten:

Code: Alles auswählen

Procedure Testtest;
var
  sss , kkk :string;
  n : integer;
begin
 n := 0 ;
 kkk := '';
 Ffufe.ZQueryFundus2.First;
 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount)); // "2" wird korrekt angezeigt
 while not Ffufe.ZQueryFundus2.EOF do
 begin
   n:= n+1;
   sss := Ffufe.ZQueryFundus2.FieldByName('CPfadG').AsString ;
   kkk := kkk + LineEnding + sss ;
//   Showmessage('Stop_01:   '+ inttostr(n) + '  '+sss);
   Ffufe.ZQueryFundus2.Next;
 end;
 Showmessage(inttostr(n) + ': ' + kkk);
end;                                        
Dieses Programm greift auf ein Datenbankfeld zu ( 'CPfadG' ); meine Testdatenbank hat nur zwei Einträge, die mit der Variablen "n" gezählt werden.

Wenn das Programm mit auskommentierter Zeile:
(// Showmessage('Stop_01: '+ inttostr(n) + ' '+sss);)
läuft, dann funktioniert alles wie erwartet:
Die Schleife wird zweimal durchlaufen. Alle Variablen werden korrekt ausgegeben.

Wenn ich aber diese genannte Zeile in der "Showmessage"-Schleife NICHT auskommentiere, dann läuft diese Schleife endlos!??
Es wird dabei ständig die zuletzt eingelesene Variable "sss" angezeigt und der Zähler "n" läuft weiter, also bei jedem Durchgang um "1" hoch gezählt.

Wie ist es zu erklären, dass diese "Showmessage"-Zeile dazu führt, dass die Schleife plötzlich endlos läuft??

Gruß Aliobaba

Lazarus Version 2.02 unter Windows
Zeos-Datenbank Programm
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
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 »

Kann es sein, das durch die längere Zeit die die Showmessage benötigt, die Verbindung zur DB gekippt wird ? Nur so kann ich mir erklären das die Query 'steckenbleibt'. Füge noch eine Abfrage ob die die Query aktiv ist mal hinzu, nicht das die gemeinerweise sich deaktiviert.
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 »

Weiß jetzt gerade nicht, ob ShowMessage eines der Formular-Events aufruft: OnShow, OnActivate? Hast du dort evtl Code, der die ZQuery schließt und neu öffnet, oder öhnliches?

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

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Code: Alles auswählen

Procedure Testtest;
var
  sss , kkk :string;
  n , a : integer;
begin
 n := 0 ;
 a := 9;
 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 ;

   if Ffufe.ZQueryFundus2.Active = true then
   begin
     a := 1;
   end
   else
   begin
     a := 0;
   end;

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

Unauskommentiert erscheint bei "Stop_02" eine "1"
Das Programm bleibt aber wieder in dieser Endlosschleife hängen und erreicht nicht die "Stop_02"-Showmessage-Zeile ??
Die Datenbank bleibt also aktiv.

Code: Alles auswählen

Procedure Testtest;
var
  sss , kkk :string;
  n , a : integer;
begin
 n := 0 ;
 a := 9;
 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 ;
{
   if Ffufe.ZQueryFundus2.Active = true then
   begin
     a := 1;
   end
   else
   begin
     a := 0;
   end;
}
   Showmessage ( 'Stop_02:   '+  inttostr(a));
   Ffufe.ZQueryFundus2.Next;
 end;
 Showmessage(inttostr(n) + ': ' + kkk);
end;
Auskommentiert erscheint bei "Stop_02" eine "9"
Auch hier bleibt das Programm wieder in dieser Endlosschleife hängen ??

Wenn ich in beiden hier gezeigten Fällen die Zeile:
"Showmessage ( 'Stop_02: '+ inttostr(a));"
auskommentiere, dann läuft das Programm durch.
Das "Showmessage" scheint also in dieser Prozedur generell ausgesprochen "unbeliebt" zu sein 8) und führt offenbar dazu, dass die Schleife nicht beendet wird. (??)

Was mich so sehr wundert:
Ich bin sicher nicht die hellste Kerze, was da Programmieren angeht. Wenn ich sehe, welch ausgefuchste Programm-Schnipsel hier im Forum gepostet werden, dann frage ich mich warum immer ich bei meinen doch recht primitiven Programm-Beispielen an so banalen Problemen hängen bleibe. :( Die Profis hier haben doch derartige Programm-Häppchen schon 1000-mal geschrieben.

LG!
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

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

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Hallo wp_xyz:

Ja , "OnShow" gibt's bei diesem Formular schon (??)

Aber wenn ich per Flag dafür sorge, dass diese "OnShow"-Prozedur nur ein einziges mal ganz zu Programmstart durchlaufen wird, dann ändert das nichts daran, dass die Schleife nicht endet.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
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 »

Zum Thema Codeschnipsel.

Ich verwende selten das Sowmessage. Normalerweise verwende ich sehe oft Debugln aus dem LazLogger Paket. Das hat den IMHO geringsten impact auf das Programm.

Unter Windows lasse ich mir einfach das ganze Anzeigen in dem ich eine Konsole öffnen lasse.

Genau deswegen würde mir soetwas nie auffallen.
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 »

Ich habe gerade ein kleines Projekt mit ZEOS rumliegen, an dem ich versucht habe, das beschriebene Problem nachzustellen. Nein - bei mir zählt der Record schön hoch, trotz ShowMessage, und das ganze findet auch ein Ende.
Dateianhänge
showmessage_in_loop.zip
(2.77 KiB) 35-mal heruntergeladen

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von charlytango »

Aliobaba hat geschrieben:
Do 14. Okt 2021, 19:58
Was mich so sehr wundert:
Ich bin sicher nicht die hellste Kerze, was da Programmieren angeht. Wenn ich sehe, welch ausgefuchste Programm-Schnipsel hier im Forum gepostet werden, dann frage ich mich warum immer ich bei meinen doch recht primitiven Programm-Beispielen an so banalen Problemen hängen bleibe. :( Die Profis hier haben doch derartige Programm-Häppchen schon 1000-mal geschrieben.
Na die hellste Kerze bin ich auch nicht (angesichts einiger Leute hier im Forum vor dene ich mich nur verneigen kann), aber Transpiration schlägt auf einigen Gebieten auch schon mal Inspiration.
Anders gesagt: Viele kommen einfach nicht (mehr) zu solchen Problemen weil sie schon oft genug drüber gestolpert sind und für sich eine Strategie entwickelt haben die für sie klappt. Und die wird ohne weiter nachzudenken eingesetzt und klappt eben weiter.

Ich z.B käme jetzt nicht auf die Idee ein Showmessage in einer Schleife reinzupacken. Oder nach einem .First.
Ich würde da ohne weiter nachzudenken ein Memo auf die Form kleben und meine Debuginfos dort ausgeben.

af0815 hat eben eine andere Strategie mit Debugln. Auf die Idee eine Konsole dazu zu verwenden ist mein Hirn auf Schienen noch nie gekommen, klingt aber auch interessant.

Mit den Zeos-Komponenten hatte ich (besonders bei dem Durchsteppen einfacher Queries) nie Probleme die ich nicht selber verursacht habe.

Hope that helps

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
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 »

charlytango hat geschrieben:
Fr 15. Okt 2021, 00:04
af0815 hat eben eine andere Strategie mit Debugln. Auf die Idee eine Konsole dazu zu verwenden ist mein Hirn auf Schienen noch nie gekommen, klingt aber auch interessant.
Hat meiner Meinung nach 3 Vorteile:
a ) Kann man sich in einer extra Konsole unter Windows ausgeben lassen (Projektoptions->Config and Target -> Win32 GUI aplication einfach deaktivieren unter Windows)
b ) Kann man auch in eine Datei umleiten zB beim Kunden um an Infos in sporadischen Fehlerfällen zu kommen (SelbsterstelltesPrg --debug-log=<file>)
c ) Lässt sich nur durch Austauschen in der uses Klausel auch deaktivieren (LazLogger, LazLoggerBase, LazLoggerDummy)

Siehe auch https://wiki.lazarus.freepascal.org/LazLogger

Ist so genial, das es vom Lazarus Team selbst verwendet wird :lol:

BTW:

Code: Alles auswählen

{$ifdef SQLDebug}DebugLn({$I %FILE%} + '->' +{$I %CURRENTROUTINE%} +' start');{$endif}
Ist bei mir häufig zum Debuggen von SQL-Routinen zu finden. Damit erspart man sich den Ort zu definieren, die Macros werden vom FPC selbst brav ausgefüllt.

Code: Alles auswählen

  try
    ....
    ....
  except
    on E : Exception do begin
      Debugln({$I %FILE%} + '->' +{$I %CURRENTROUTINE%} +' Exception =>' + E.Message);
    end;
  end;
Siehe https://www.freepascal.org/docs-html/prog/progsu41.html
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,

... und ich habe weiter probiert:

Prozedur Testtest2 läuft NICHT durch, läuft aber durch bei auskommentiertem Showmessage in der Schleife

Prozedur Testtest3 läuft immer durch, auch mit Showmessage in der Schleife.

?????
-> Ich fürchte, ich muss auch dieses Problem wieder mal einfach resigniert zur Kenntnis nehmen.
... aber wenn noch jemand eine Idee hat; ich bleibe natürlich interessiert.

Danke jedenfalls für Eure Hilfsbereitschaft!!

Code: Alles auswählen

Procedure Testtest2;
var
  n : integer;
begin
 n := 0 ;
 Ffufe.ZQueryFundus2.First;
 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
 while not Ffufe.ZQueryFundus2.EOF do
 begin
   n:= n+1;
   Showmessage ( 'Stop_02:   ');
   Ffufe.ZQueryFundus2.Next;
 end;
 Showmessage(inttostr(n) + 'Ende: ' );  // Programm läuft NICHT bis hierher durch
end;

Procedure Testtest3;
var
  n : integer;
begin
 n := 0 ;
 Ffufe.ZQueryFundus2.First;
 Showmessage( inttostr(Ffufe.ZQueryFundus2.RecordCount));
 while n < 4 do
 begin
   n:= n+1;
   Showmessage ( 'Stop_02:   ' + inttostr(n));
   Ffufe.ZQueryFundus2.Next;
 end;
 Showmessage(inttostr(n) + 'Ende: ' );  // Programm läuft PROBLEMLOS bis hierher durch
end;             
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
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 »

Also ich bin mir ziemlich sicher, daß es etwas ist, das die ZQuery wieder an den Anfang setzt (wie wp_xyz vermutet hat)
Lass dir doch vor und nach dem Showmessage mal den aktuellen Datensatzinhalt in zwei Variablen ausgeben und vergleiche die dann.

Das ist ein kleiner Nachteil der Eventgesteuerten Programmierung.
Da kann einer "reinfunken".

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

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Danke, Fliegermichl,

vielleicht wirfst Du nochmal einen Blick auf den Programmcode, den ich ganz oben beim initialen Beitrag gepostet habe.

Bei nicht auskommentiertem ShowMessage innerhalb der Schleife durchläuft die Schleife die Datensätze schon, allerdings wird beim letzten Datensatz der "Ausstieg" ignoriert:
Der Zähler (Variable "n") läuft weiter, aber die Datenbankabfrage bleibt bei dem letzten(!) Eintrag (Variable "sss") stets unverändert stehen. Bei auskommentiertem "ShowMessge" wird die Schleife korrekt beendet und das Programm verhält sich wie erwartet.
Auch ein "Application.ProcessMessages" an diversen Stellen habe ich schon probiert: Nützt nichts.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
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 »

Kannst du bitte mal ein kleines funktionierendes Demoprogramm einstellen, damit man das Problem nachvollziehen kann?
Das Problem liegt mMn. ganz sicher nicht in der procedure testtest.

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

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von Aliobaba »

Das ist für mich als nicht versierter User nicht einfach, da ich eine gesamte Datenbankanwendung in diesem Demoprogramm implementieren muss (und sowas funktioniert bei mir meist nur eher "zufällig" 8) ).

Und auch wenn das Demoprogramm dann problemlos laufen würde hilft das ja auch nicht weiter, denn es darf doch unter keinen Umständen sein, dass eine Schleife problemlos und fehlerfrei durch läuft, wenn kein ShowMessage drin ist, aber dieselbe Schleife keinen Ausstieg findet, wenn ein ShowMessage drin vorkommt, ganz egal, in welchem Zusammenhang diese Schleife in einem Programm steht.

Ich finde, man darf erwarten, dass ein Programm Zeile für Zeile durcharbeitet.
Darauf kann man sich aber nicht verlassen; ich habe bei einem anderen Programm schon mal die Beobachtung gemacht, dass eine Prozedur (Ich weiß jetzt nicht mehr, ob eine Schleife da drin war) nicht mit "exit" verlassen werden konnte ohne dass noch Befehle abgearbeitet werden, die NACH diesem "exit" erst in der Befehlsliste im Code gestanden haben.

Nach meiner laienhaften Meinung deutet das Programmverhalten auf (sagen wir es mal vorsichtig) "Schwächen" hin. Und ja - ich weiß - so ein Urteil steht mir nicht zu, dazu habe ich viel zu wenig Ahnung von der Materie.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Seltsames Programmverhalten einer While - Schleife

Beitrag von siro »

Mahlzeit zusammen.

Mit ShowMessage scheint es schon öfters Probleme gegeben haben,
ich verweise mal hier auf eine Thread:
https://entwickler-ecke.de/topic_wenn+S ... 626,0.html

Die Procedure sieht ja wie fogt aus:

procedure ShowMessage(const aMsg: string);
begin
NotifyUser(ConvertLineEndings(aMsg), idDialogBase);
end;

procedure NotifyUser(const DialogMessage : String; DialogType : longint);
Da ich die Procedure zunächst nicht finden konnte,
habe ich ein Testprogramm mal durchgesteppt, das scheint also Betriebssystem sowie Versions abhängig zu sein.
Da steckt ein haufen Code hinter....
Vermutlich liegt das bei "Windows" hier drin verankert: function TWin32WidgetSet.PromptUser

Das löst jetzt zwar nicht das Problem, aber ich würde mir einfach mal in Lazarus einen "eigenen" ShowMessage Dialog bauen,
dann sollte das Problem eigentlich nicht mehr auftauchen. Wäre ein Versuch Wert.

Siro
Zuletzt geändert von siro am Fr 15. Okt 2021, 11:46, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten