Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.024 Beiträge
 
Delphi 12 Athens
 
#15

AW: OpenDialog - Relikt in *.pgn-Tool

  Alt 22. Dez 2014, 13:27
Um aber nochmals zum Thema zurück zu kommen. Hast du denn "das Verbotene" schon ausprobiert?
Ich bin kein Arzt und würde mir deshalb auch niemals erlauben, irgendeine Diagnose zu stellen. Informatik habe ich auch nicht studiert und das Programmieren habe ich mir weitestgehend selbst beigebracht. Ich traue mir aber dennoch zu, in Bezug auf Delphi/Pascal-Programmierung durchaus fundierte und belastbare Aussagen zu treffen und Empfehlungen zu geben, die überwiegend auf einer über 30-jährigen Erfahrung beruhen.

Daher, um für die noch nicht so lange zugehörigen Forenmitglieder mal zu verdeutlichen, warum Application.ProcessMessages "verboten" ist: Mit diesem Aufruf werden Nachrichten aus der MessageQueue abgearbeitet. Das mag für das Neuzeichnen des Forms hier vielleicht noch erwünscht sein, für andere Eventhandler fällt das aber im Allgemeinen unter die Rubrik "unerwartet".

Nehmen wir z.B. mal diesen einfachen Code in einem Eventhandler an:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  DoSomeStuff;
  if OpenDialog1.Execute then begin
    Application.ProcessMessages;
    DoSomeOtherStuffThatNeedsSomeTime;
  end
  else begin
    DoSomeEvenOtherStuff;
  end;
end;
Bei einem Click auf Button1 wird nun zunächst DoSomeStuff aufgerufen, dann der Dialog geöffnet und nach Bestätigen beendet. Nehmen wir nun noch an, daß der User während DoSomeStuff nochmal auf den Button klickt, sei es aus Ungeduld, fehlendem Feedback des Programms oder motorischer Unzulänglichkeit. Das nun folgende Application.ProcessMessages wertet diesen Click aus, ruft DoSomeStuff auf und öffnet den Dialog erneut. Dabei ist DoSomeOtherStuffThatNeedsSomeTime aber noch gar nicht gelaufen. Wird der Dialog abgebrochen, erfolgt ein Aufruf von DoSomeEvenOtherStuff, der Eventhandler wird beendet, das Application.ProcessMessages ebenso und es folgt ein DoSomeOtherStuffThatNeedsSomeTime.

Aus dem eigentlich vorhersehbaren und durchaus überschaubaren Event-Handling ist ein ziemliches Wirrwar im Programmablauf geworden, daß selbst erfahrene Programmierer kaum noch nachvollziehen, geschweige denn in den Griff kriegen können. Und hier habe ich bewusst nur den einen Eventhandler betrachtet. Es kann auch durchaus zu konkurrierenden Abläufen in mehreren Eventhandlern auch in unterschiedlichen Forms kommen. Meistens versucht man dann durch zusätzliche Flags das Reentering der Eventhandler zu unterbinden. Das fördert aber nicht gerade die Lesbarkeit und Wartbarkeit eines Programms.

Ich weiß nicht, wie oft ich schon sporadische Laufzeitfehler in fremdem Code suchen musste, bei dem sich das Problem auf mindestens einen Aufruf von Application.ProcessMessages zurückführen ließ. Dabei schließe ich frei verfügbare und käuflich erwerbbare Bibliotheken (z.B. RxLib oder QuickReport um nur zwei zu nennen) gar nicht aus. Das ist dann ganz besonders gemein, da der eigentliche Programmcode ja durchaus korrekt sein mag und es nur wegen eines entsprechenden Aufrufs innerhalb der Bibliothek zu der Fehlfunktion kommt.

Deshalb ist Application.ProcessMessages meiner Meinung nach einfach verboten. Es ist nur ein Hilfmittel um eigentlich schlechten oder gar falschen Code trotzdem noch halbwegs zum Laufen zu bringen. Man erweist sich dadurch also nur einen Bärendienst.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat