Delphi a Application.Terminate v podprograme?
Mam program ktory na zaciatku pomocou funkcie nacitava udaje z textoveho suboru (kde su rozne navestia a podla nich vie o aky typ udajov ide). Pokial navestie v zdrojovom subore nenajde tak zobrazi spravu ze nenasiel dane udaje. Tu nastava problem. Kedze uz nieje mozne dospiet k sparavnym vysledkom vypoctou tak som chcel program ukoncit pomocou Application.Terminate v tejto funkcii. Neviem ale z akeho dovovodu program pokracuje dalej a k ukonceniu dojde az po dokonceni vypoctu (ktory je samozrejme zle kedze nemal vsetky potrebne vstupne udaje). Funkcia sa sklada z casti try, finally a except a v casti finally po CloseFile() som zavolal proceduru Application.Terminate ked neboli najdene pozadovane udaje vo vstupnom subore.
Mohol by mi niekto vysvetlit preco sa program neukonci ale pokracuje dalej? Pripadne ako vyriesit tento problem?
Program se ukončí, až se dostane k lizu smyčka ProcessMessages - to jest až aplikace začne zahálet a čekat na akci operátora.
To potom znamená, že ak sa nachádza tento príkaz niekde v strede metódy, tak vykonávanie programu pokračuje ďalej? V tom prípade to treba riešiť takto:
To ti nepomůže. Application.Terminate je procedura, z jejíhož volání se to musí vrátit. Sice se volá API funkce PostQuitMessage, ale všechno se musí dodělat a nastaví se jen příznak Application.Terminated, který se testuje uvniř smyčky zpracování zpráv - a tam se musí řízení programu vrátit po poctivém dodělání všech procedur - takhle to vypadá uvnitře Application.run:
Až se provádění programu vrátí do smyčky zpracování zpráv (uvnitř Application.Run), pak se to může ukončit.
Při programování řízeném událostmi (např. zprávami Windows) a v objektovém programování Delphi, nelze tak jednoduše programově aplikaci ustřelit pod prd*elí.
Vdaka za objasnenie ako to funguje Vytvoril som si v ramci tej funkcie Label PredcasneUkoncenie; Pomocou toho sa dostanem do sekcie except a tam sa to uz pomocou Application.Terminate; da ukoncit. Nieje to "pekne" riesenie ale funguje.
Povazujem tento problem za vyrieseny.
Není zač. Tak ti tento thread "ofajfkovávám".
Ak to chceš krajšie, tak tú funkciu volaj a požaduj návratovú hodnotu. Ak budeš chcieť ukončiť aplikáciu, tak len nastav správne návratovú hodnotu a ukonči ju predčasne pomocou Exit; a vo funkcii, z ktorej túto funkciu voláš otestuj návratovú hodnotu a jednoducho pošleš aplikáciu odkiaľ prišla. V Pascale nie je pekné používať goto. To je len vírus, ktorý sa šíri z prvých verzií BASICu. Správny programátor nikdy v aplikácii nepoužíje goto.
Edit: Ja som na predčasné ukončenie funkcií používal Abort;, ale len do tej chvíle, kým nezačal Delphi 7 protestovať (Delphi 6 v pohode). Jan Fiala ma ohľadne toho poučil, takže to riešim buď návratovými hodnotami alebo inak, ale nikdy nie goto alebo Abort;.
Ano, GOTO těžce znepřehledňuje program. Když jsme dělali první PASCAL na sálový počítač a FEL fakultě pro výuku programování, neměl z "výchovných" důvodů vůbec GOTO implementován. Pak jsem léta programoval ve FoxPro, které GOTO také nezná a tak už ani nevím, že takový příkaz existuje a vůbec mi nechybí.
Mne tiež nie. Viem, že nový BASIC sa už viac blíži Pascalu ako k originálnemu BASICu a ja keď som prešiel na Turbo Pascal z Quick BASICu, tak som zistil, že goto je ozaj zbytočný príkaz. Inak je to zaujímavé, že BASIC sa viac približuje už Pascalu a Pascal pre zmenu zas k C++. Jediná vec, čo mi začala na BASICu vadiť, keď som prešiel na Pascal je, že nevyžaduje deklačnú časť. Pascal to núti používať a to je dobre, aspoň programátor vie, čo používa. Ale to už idem trochu od témy, takže hádam stačí.
Skusal som to s Exit; ale to aplikaciu neukoncilo a ani samotnu proceduru v ktorej som to volal (navratovu hodnotu testujem preto tam mam na citanie funkciu ktora je typu Boolean;). Ja som to chcel vyriesit bez goto a preto som pisal ze to nieje "pekne" riesenie. Mohol by si tu dat odkaz na tu diskusiu s JF.
Oprava:
Exit vykonavanie procedury skutocne zastavi (nevsimol som si pred tym ze som bol este v inej procedure). Pri navrate z nej som si dal dalsiu podmienku na otestovanie v tvare
Takze da sa to vyriesit i bez goto a s niekolkymi riadkami kodu naviac
Tá diskusia bola na ICQ, ale okrajovo som ten Abort, čo vyhodil chybu spomenul tu:
SubChild.asp
Edit: Asi sa pustím do hľadania všetkých programovacích vlákien, ktoré som si povytváral na živě. Mám skúsenosť, že vlákno, ktoré hovorilo k téme som už nenašiel a musel som vytvoriť nové. Jednalo sa o nemožnosť spojazdnenia siete. Takže to asi zozbieram a možno sa niektorí admini aj potešia tomu, že budú mať podklady na vytvorenie databázy znalostí tu na poradni.
Bacha na to! Když tady uvedeš odkaz do Big Brothera, tak to tam okamžitě M.L. zuřivě smaže
Veď práve preto chcem všetky moje programovacie otázky vycucať skôr ako bude neskoro.
Application.Terminate je korektné ukončenie programu. Ja mám skôr pocit, že tento riadok sa nevykoná, čiže dojde k "preskočeniu" tohto riadka a preto to pokračuje. Skontroluj si podmienky a či tam náhodou nemáš nejaký skrytý if, ktorý by mohol v rámci pokračovania príkazu na ďalšom riadku považovať tento príkaz za "svoj". V každom prípade, najrozumnejšie by asi bolo, keby si nám tento "nefunkčný" kód (aspoň metódu, o ktorej je reč) zverejnil.
Ak uz chces program ukoncit tak pouzi procedurku Halt. Je to sice nasilne ukoncenie, ale co uz... mne to uz viackrat pomohlo...
Halt je presne to co som chcel od zaciatku. Dokaze to ukoncit priamo vo funkcii kde nacitavam data zo zdrojoveho suboru a nemusim postupne zastavovat procedury ako pri Exit ani pouzit Label.
Dakujem
Ale Halt; si po sebe neuprace. Korektné je len Application.Terminate;. Halt je na použitie vhodný vtedy, ak je program "načatý" nejakou chybou a nedokáže sa "spamätať" a potrebuješ vrátiť riadenie systému. Napríklad nabúraš pamäť a pokračovanie programu nie je vhodné.
Edit:
Halt performs an abnormal termination of a program and returns to the operating system.
To perform a normal termination of a Delphi application, call the Terminate method on the global Application object. If the application does not use a unit that provides an Application object, call the Exit procedure from the main Program block.
Exitcode is an optional expression that specifies an exit code for the program.
Co sa mysli pod?
To je logické. HALT prostě ustřelí aplikacei a basta fidli, ani programátor nemá šanci uvolnit objekty. W9x jsou po několika takových pokusech na hubě kvůlivá uškrcení v paměti a na prostředcích. W typu NT to přežijou kapánek víckrát, ale také ne nekonečně.
Proto Application.Terminate nahodí Application.Terminated := true; aby všechny komponenty (včetně programátora ) věděli, že se to ukončuje a podle toho se zařídili. A proto se to může ukočit až v čase IDLE (když program zahálí a všechny požadavky jsou vyřízeny).