Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#17

Re: Problem mit Delay

  Alt 18. Feb 2008, 10:49
Jain man könnte ihn so lassen da zwischen den beiden Aufrufen im While Kopf von Gettickcount() kein allzugroßer Fehler entstehen wird, allerdings ist er eben unellegant da man zweimal überflüssigerweise GetTickCount() aufruft. So wie meine Originalfunktion ist ist sie schon am besten, man muß halt Überlaufprüfungen abschalten, fertig. Man könnte eine Sache abändern, nämlich den Parameter Millisecinds als DWord statt Cardinal deklarieren, ist aber eine Schönheitskorretur und wird mit an Sicherheit grenzender Wahrscheinlichkeit dazu führen das diese Funktion nicht mehr in allen Delphiversionen ohne Fehler/Warnunung komplierbar ist. Eben auf grund der ständigen Änderungen am Compiler und Windowsimporten, Cardinal/DWord als Integer oder als 32Bit vorzeichenlos, GetTickCount mal mit Integer mal DWord (32Bit) Rückgabewert, WaitFor() Parametertypänderungen von Timeout usw. Die Kunst dabei war es also den Source möglichst so zu schreiben das er mit allen Delphiversionen relativ sauber läuft.


Wie gesagt: Die Benutzung von Delay() ist ein starkes Indiz dafür das der Programmierer generell irgendwas konzeptionell falsch macht. Windows/VCL basierte Anwendungen sollten immer ereignisbasiert arbeiten, statt auf Basis eines Pollings und das macht Delay() nämlich. Das Dumme dran ist nun die Forderung das das Anhalten der kompletten Anwendung, indem man die Veränderung ener Zeitspanne pollen möchte, nicht erwünscht ist. Also kommt man auf die eigentlich dummme Idee während diesem Polling noch Application.ProcessMessages aufzurufen. Einige denken sich: rufe ich doch Appplication.ProcessMessages permanent auf, also auch wieder Polling des Messagequeues und wundern sich dann das die CPU Auslastung auf 100% hochschnellt obwohl fast garnichts im System passiert. Andere versuchen es cleverer zu lösen, sie benutzen WaitForMultipleObjects() usw. und benutzen damit wenigstens teilweise ein ereignisbasiertes System. Sie vermeiden so wenigsten das unnötige Verbraten von Rechenzeit. Aber beide machen im Grunde einen Denkfehler denn sie handeln sich mit dem nun alternativen Pfad der Messageabarbeitung durch ein nicht mehr zentralisiertes Aufrufen von Application.ProcessMessages an anderer und erstmal unsichtbarer Stelle übelste Fehler ein. Dann kommt irgendwan eine Anfrage hier in der DP warum ihre Anwendung beim Beenden ständige Exceptions auslösst die final in einem RunTime Errror endet. Logisch: Anwendung ist in Delay() wird nun von User terminiert über Schließenbutton, MainForm wird zerstört befindet sich aber noch in Delay(), Delay() wird irgendwan mal fertig springt zurück in das nun zerstörte Form und schwups Exceptions. Und da diese Beendigung auch noch in der Finalizierungsphase stattfindet, also das Program in der Kette dr Unit-Finalization-Sektionen sich befindet, der Exceptionhandler da schon längst deinstalliert wurde, sieht man im besten Falle nur noch Runtime Errors. Und das Ganze liegt nur daran das man ein Delay() aufruft und darin über Application.ProcessMessages eine alternativen Messageabarbeitungspfad aufmacht.
Und was macht dieser Programmierer in seiner Verzweiflung -> er versucht mit TerminateProcess() oder TerminateThread(MainThread) das Problem zu "lösen" indem er radikal seine eigene Anwendung abschlachtet. Fehlerursache nicht gefunden aber Problem gelösst meint er, aus den Augen aus dem Sinn. Ändern tut es nichts an dem Fakt das dieser Programmierer rein konzeptionell garnicht programmieren kann !


Probiers aus: Nehme ein TForm + Button1 drauf. In Button1Click() dann eine Delay() das mehrere Minuten dauert. Vor den Aufruf dieses Delay() noch ein ShowMessage('ich warte'), dann Delay(Minutenlang) und danach ein ShowMessage(Self.Caption). Dann im Form.Ondestroy eine ShowMessage('ich zerstöre TForm'). So nun starten und auf Button Clicken. Danach das Formular schließen und sehen was passiert.

Gruß Hagen
  Mit Zitat antworten Zitat