![]() |
Timer direkt aufrufen
@Alle
Ein Problem, das während des Programmierens auftrat: Ein Timer setzt erst nach der abgelaufenen Zeit ein. Das ist aber für mich zu spät. Wie kann ich den Timer direkt aufrufen, damit ich bei Programmstart z. b. beim ONSHOW Ereignis den Timer sofort durchlaufe? Beste Grüße Go2EITS |
Re: Timer direkt aufrufen
du willst das das ereignis des timers direkt aufgerufen werden kann?
lager es in eine andere prozedur aus, die dann vom timer und von dir direkt aufgerufen werden kann. |
Re: Timer direkt aufrufen
die Frage ist etwas unklar, ich nehme mal an, du hast beriets einen Timer, und in der OnShow-Routine setzt du dann
Delphi-Quellcode:
Du kannst die onTimer-Routine aber auch direkt aufrufen, bsw.,
Timer1.enabled := true;
Delphi-Quellcode:
MfG
onTiner1();
Timer1.enabled := true; Kolbaschedder |
Re: Timer direkt aufrufen
*autsch*
Nein, ich würde auch dafür plädieren, dass Du den Code in eine eigene Routine auslagerst und diese dann gezielt aufrufst. Die OnTimer-Methode per Hand aufzurufen ist in meinen Augen absolut unsauber. |
Re: Timer direkt aufrufen
Was soll daran unsauber sein.
Die onTimer ist ne ganz normale Prozedur. Sie wird vom Timer-Objekt lediglich als Callback benutzt. |
Re: Timer direkt aufrufen
Wenn das Wörtchen Sender nicht wär, ...
|
Re: Timer direkt aufrufen
Delphi-Quellcode:
dann kannst du sogar anhand des Senders unterscheiden, wer dich aufgerufen hat
Timer1Timer(nil)
|
Re: Timer direkt aufrufen
Es ist trotzdem unsauber.
Routinen- und Methodenbezeichner müssen mehr oder weniger selbsterklärend sein. OnTimer bedeutet für mich "das Ereignis, das aufgerufen wird, wenn der Timer abläuft" und nicht "das Ereignis, das aufgerufen wird, wenn der Timer abläuft und manchmal auch zwischendurch, wenn der Programmierer grad Lust drauf hat". |
Re: Timer direkt aufrufen
dann schreiben wir eben eine Methode
procedure MachIrgendwas(Sender :TObject); in der formCreate dann Timer1.OnTimer := MachIrgendwas; dann dürfte es sauberer sein. Oder wir benennen die "Timer1Timer" einfach in "Timer1TimerOderWannAuchImmer" um. |
Re: Timer direkt aufrufen
Letztendlich ist es doch völlig egal ob es nun sauber oder unsauber ist, hauptsache der Programmierer kommt damit klar. Wenn mehrere Leute mit dem Quelltexten arbeiten sollten wäre es aber wohl doch etwas strange.
|
Re: Timer direkt aufrufen
Zitat:
Jeder Aufruf einer TNotifyEvent-Prozedur ist unsauber, ist sie nicht ein Eventhandler einer Komponente. Zitat:
[edit] Zitat:
[/edit] |
Re: Timer direkt aufrufen
@fwsp
Das wollte ich nicht. Doppelter Code vergroßert unnötig die EXE. @kolbaschedder Genauso geht es. @3_of_8 Prinzipell magst Du recht haben. Das Problem hatten wir schon mit den Aufruf von Button1.click. Zitat:
Zitat:
@Daniel Ihr seid erfahrener. Offen gesagt, meine Button1.click Aufrufe machten mir überhaupt keine Probleme im Projekt Delphi Cleaner. Nicht ein einziger Fehler/BUG war darauf zurückzuführen. Für mich zählt Praxis, nicht Theorie. Das Einzige was mich wunderte, war ein dass ein Checkbox1.checked:=StrToBool(h); die Checkbox1.click Methode aufgerufen hat... Aber das ist eine andere Frage. Zitat:
Vielen Dank für die Antworten. Das Problem ist für mich gelöst. Top! :thumb: Go2EITS |
Re: Timer direkt aufrufen
Vielleicht ist das genau das Problem: In der Praxis geht es durchaus, so wie Du das beschreibst. ;-) Zumindest erstmal ...
Auch wenn Du Deinen Fokus lieber auf die Praxis legst, möchte ich ein wenig Theorie beisteuern: Eine Methode sollte einen definierten Zweck haben. Und zwar genau einen. Aus diesem Zweck ergibt sich in den meisten Fällen auch ein brauchbarer Name für die Methode. Hier hat man auch eine schnelle Möglichkeit zur selbstkritischen Kontrolle: Wenn einem auf Teufel komm raus kein brauchbarer Name für eine Methode einfallen mag, so ist das ein ganz deutliches Indiz dafür, diese Methode zu überdenken und den Code ggf. anders zu strukturieren. Button1.Click() ist die Methode, die aufgerufen wird, wenn die zugehörige Schaltfläche gedrückt wird. Fertig aus. Diese Methode hat eine sehr enge Bindung zu Deiner Programmoberfläche und man kann sie als Teil derselbigen ansehen. Der Klick auf den Button soll ja etwas auslösen und das sollte diese Methode deligieren. Wenn jetzt in Deinem Datenmodell etwas verändert werden soll, zum Beispiel eine Variable gesetzt werden soll, dann hast Du eine Methode, die sich darum kümmert und etwaige Plausibilitäts-prüfungen vornimmt. Das aber hat mit dem Button nichts mehr zutun. Die Variable könntest Du auch ändern, wenn Dein Programm zum Beispiel über ein Script gesteuert wird. Auch dann müsstest Du ja etwaige Plausibilitäten rund um diese Variable prüfen. Das kannst Du nur dann erreichen, wenn Du den Code kapselst. Alleine durch die Kapselung von Code holst Du Dir auch keine negativen Seiteneffekte ins Haus. Nun kannst Du jetzt sagen: "Ach was, läuft doch" - und hast in Deinem Fall sogar Recht damit. Mir ist es gleich, wie Du Deinen Code schreibst und ich will jetzt nicht sagen "Du musst, Du musst, Du musst...". Aber als Denk-Anstoß solltest Du das mitnehmen. Ich bin ja nicht der einzige, der so denkt. Das Ding is', dass sich diese Denkweise in der Software-Entwicklung weitgehend etabliert hat. Stichworte wären: "Kopplung von Modulen", in diesem Zusammenhang auch "Trennung von GUI und Programm-Logik" oder aber das gute alte "Model-View-Controler"-Prinzip. Selbst verständlich steht es Euch frei, zu entwickeln, wie Ihr mögt - aber unternehmt bitte nicht den aussichtslosen Versuch, o.g. Konzepte mit einem Satz allgemeingültig wegzuwischen. |
Re: Timer direkt aufrufen
Zitat:
Zitat:
Nebenbei hat auslagern nichts mit doppelten Code zu tun! Doppelter (gleicher) Code wäre tatsächlich völlig unangebracht. Aber auslagern heißt nur, dass du für die Lösung eines Problems eine Methode verwendest. Typischerweise lagert man Code aus, um ebend doppelten Code zu vermeiden. Das deine Exe um ein paar Byte größer wird und du auch noch ein paar nanosekunden für den Aufruf der Prozedur verlierst, wirst du kaum merken! Und ich bin der Meinung, da die Routinen im Timer genau so abzuarbeiten sind, halte ich, nur um sauber zu arbeiten, eine Auslagerung der Routinen nicht für sinnvoll. Der Timer wird nur einmalig aufgerufen, ist währenddessen nicht aktiv und läuft dann "normal". Igendwelche Seiteneffekte oder undefinierte Programmzustände sind in meinem Fall ausgeschlossen. Zitat:
Möchtest du Seiteneffekte ausschließen, dann solltest du funktional Programmieren. Schau dir mal sowas wie Haskell an, da gibt es dann auch die Lazy-Evaluation. Die ist immer ein eindeutiges Zeichen dafür, dass es keine Seiteneffekte (eben auch keine Zustände) geben kann. Da du aber imperativ bis Objekt Orientiert arbeitest, existieren Zustände, ergo sind Seiteneffekte durchaus möglich. Ob sie (ungewollt) auftreten oder nicht ist dann so eine Sache, genau wie undefinierte Programmzustände hat das aber wenig damit zu tun, wie du hier die Methode aufrufst. Das Timer1 weder ein Routinen noch ein Methodenbezeichner ist, ist dir doch hoffentlich klar?! Zitat:
Weißt du, ein paar wichtige Ziele gibt es für jede Software, da wären unter anderem immer Robustheit, Sicherheit, Erweiterbarkeit und Wartbarkeit (und noch viele viele mehr). Nehmen wir mal die letzten beiden, Erweiterbarkeit und Wartbarkeit haben viel miteinander gemeinsam. Sagen wir der Delphi Cleaner (was auch immer der kann) wird super erfolgreich und muss erweitert werden. Wer ausser dir wird denn jetzt wissen was Button1.Click macht? Klar, die Anwendung hat vielleicht nur einen Button, aber was ist wenn die 5 hat? Was genau ist dann die Aussage davon, dass Button1 gedrückt wurde? Nebenbei bemerkt wenn du 5 Button in einem Programm hast, dann wirst du in einem halben Jahr auch nicht mehr wissen, welcher Button was machte. Das der Code funktioniert, das ist nicht die Frage/das Ziel. Du hast sicherlich schon etwas von QuickAndDirty gehört. Man findet immer wieder Leute, die so arbeiten, aber kaum in großen Firmen. Wenn du einen Kunden hast, der ein paar Ansprüche stellt, dann kommst du damit nicht weit. Die Bedürfnisse des Kunden sind in der Regel unscharf (zu Beginn eines Projektes), es gibt das Problem der Kommunikation (was will er wirklich, wie will er es, was will er nicht, ...). Die Entwicklung ist ein agiler Prozess, wenn dein Kunde dein Produkt sieht (einen Zwischenstand), dann kann der noch leicht Änderungswünsche einbringen. Da ist es dann sehr viel einfacher, wenn du die Logik schön ausgelagert hast und alles so benannt ist, dass jeder weiß welche Funktion was tut (und welcher Button wofür zuständig ist). Solltest du mit mehr als einer Person am Projekt arbeiten, ist anders keine Arbeit möglich. Aber auch wenn du allein an einem solchen Projekt sitzt, dadurch dass die einzelnen Problemlösungen ausgelagert sind, musst du kein Copy&Paste anwenden (was sehr fehleranfällig ist) wenn du hier einen Teil änderst. Nicht zuletzt solltest du auch die GUI von dem Rest trennen, denn gerade das Design ändert sich häufiger als der gesamte Rest. Natürlich läuft auch jede andere Lösung, aber Änderungswünsche änden schnell in einem Chaos und keine Firma ist bereit sich ewig an einen Entwickler zu binden (weil ausser ihm nie jmd. durch den Code steigen wird). Gruß Der Unwissende (Roter Kasten, nur kurz Daniel's Beitrag überflogen, sieht aber nach der gleichen Richtung wie dieser Beitrag aus, wenn auch etwas ausführlicher und schöner von Daniel) |
Re: Timer direkt aufrufen
[Senf]
Sorry wenn ich ein wenig widerspreche. Für mich ist z.B. der direkte Aufruf Timer1Timer(Timer1); besser lesbar, weil ich hier direkt sehe, dass dort nichts anderes geschieht als beim eigentlichen Timer-Ereignis selbst. Damit meine ich aber wirklich nur den Fall, dass exakt das gleiche stattfindet. Sobald in der Routine eine Unterscheidung stattfindet, welcher Sender übergeben wird und ob jetzt wirklich der Timer getriggert hat oder ob die Routine manuell aufgerufen wurde, gebe ich euch wieder Recht: das gehört ausgelagert in eine separate Prozedur. [/Senf] |
Re: Timer direkt aufrufen
Hossa,
Da habe ich mit meiner Antwort ja ganz schön was ausgelöst. In diesem Fall sehe ich es allerdings nicht ganz so tragisch. der Aufruf
Delphi-Quellcode:
ist nun wirklich unproblematisch. Vielleicht wäre die Variante
Timer1Timer(nil);
Timer1.enabled := true;
Delphi-Quellcode:
Richtiger.
if not Timer1.enabled then
Timer1Timer(nil); end; Timer1.enabled := true; bzw., wäre ein Timer-Objekt mit einer startImmediate-Eigenschaft wünschenswert. Zu den anderen Dingen muss ich euch recht geben. Das erste, was man mit einer neuen visuellen Komponente machen sollte, ist, ihr einen sinnvollen NAmen zu geben. Genauso gehört die Funktionalität des Programms in eigene Methoden. Die GUI sollte diese Funktionalität lediglich steuern. Bsp.
Delphi-Quellcode:
procedure ParseXML(fName: string);
begin .... end; procedure btnParseFile.click(sender : TObject); begin if FileExists(currentFile) then ParseXML(currentFile) else application.MessageBox('File not found','Fehler',0); end; |
Re: Timer direkt aufrufen
@Daniel
Besten Dank für Deine Ausführungen. Eine gute Namensgebung ist schon mal eine gute Voraussetzung für das Gelingen des Projektes. Sie hat mich im Projekt Delphi Cleaner bei der Fehlersuche eine Menge Zeit gekostet, bis ich sinnvolle Namen vergab. Komplexe Proceduren habe ich dann vereinfacht und gesplittet. Diese Proceduren dann jeweils als Methode jeweils zu implementieren entspricht wohl Deiner Aussage. Dies ist dann wohl die Kapelung, die Du meinst. Eine
Delphi-Quellcode:
ist dann nicht zu empfehlen, dann ist wohl die theoretische Lösung der Profis besser:
Procedure GoTimer;
begin form1.timer1.timer(nil) end;
Delphi-Quellcode:
in der formCreate dann
procedure MachIrgendwas(Sender :TObject);
Delphi-Quellcode:
wie von kolbaschedder vorgeschlagen.
Timer1.OnTimer := MachIrgendwas;
Ich glaube, ich habe es verstanden. Beste Grüße an die DP. [Roter kasten]
Delphi-Quellcode:
sowie meine Auslagerung
procedure TForm1.Timer2Timer(Sender: TObject);
begin if Silent then Exit; form1.label2.Caption:=inttostr(count)+' Files'; form1.label4.Caption:=bytestostr(size); application.processmessages; end;
Delphi-Quellcode:
verdopplet in dem Falle den Code.
procedure TForm1.Machrigendwas(Sender: TObject);
begin if Silent then Exit; form1.label2.Caption:=inttostr(count)+' Files'; form1.label4.Caption:=bytestostr(size); application.processmessages; end; @Der_Unwissende Zitat:
Nur weil ich einen Timer oder Buttondirekt aufrufe? Ist es so ein Posting eine Zurechtweisung wert? Damit ist, bei allem Respekt, dieses Thema für mich erledigt, auch wenn in Bezug der der Entwicklung der Software recht hast. Inwieweit ich darüber denke, ist bei Deinem Betrag dann absolut irrelevant. Go2EITS |
Re: Timer direkt aufrufen
noch richtiger wäre :
Delphi-Quellcode:
procedure Timer1.Timer(Sender: TObject);
begin MachirgendWas(Sender); end; procedure TForm1.Machrigendwas(Sender: TObject); begin if Silent then Exit; form1.label2.Caption:=inttostr(count)+' Files'; form1.label4.Caption:=bytestostr(size); application.processmessages; end; |
Re: Timer direkt aufrufen
[Noch ein Senf]
Delphi-Quellcode:
So mach ich das...
// Echter Fake
If Assigned(Timer1.OnTimer) then Timer1.OnTimer(Timer1); // Oder erkennbarer Fake If Assigned(Timer1.OnTimer) then Timer1.OnTimer(nil); Dann weiß man, ob's ein fake Aufruf ist oder nicht [/Noch ein Senf] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz