Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno 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?

Předmět Autor Datum
Program se ukončí, až se dostane k lizu smyčka ProcessMessages - to jest až aplikace začne zahálet a…
Rce 22.06.2006 22:26
Rce
To potom znamená, že ak sa nachádza tento príkaz niekde v strede metódy, tak vykonávanie programu po…
msx. 22.06.2006 22:31
msx.
To ti nepomůže. Application.Terminate je procedura, z jejíhož volání se to musí vrátit. Sice se volá…
Rce 22.06.2006 23:07
Rce
Vdaka za objasnenie ako to funguje;-) Vytvoril som si v ramci tej funkcie Label PredcasneUkoncenie;…
Andrej 23.06.2006 00:00
Andrej
Není zač.;-) Tak ti tento thread "ofajfkovávám".:-)
Rce 23.06.2006 00:21
Rce
Ak to chceš krajšie, tak tú funkciu volaj a požaduj návratovú hodnotu. Ak budeš chcieť ukončiť aplik…
msx. 23.06.2006 01:03
msx.
Ano, GOTO těžce znepřehledňuje program. Když jsme dělali první PASCAL na sálový počítač a FEL fakult…
Rce 23.06.2006 01:18
Rce
Mne tiež nie. Viem, že nový BASIC sa už viac blíži Pascalu ako k originálnemu BASICu a ja keď som pr…
msx. 23.06.2006 13:51
msx.
Skusal som to s Exit; ale to aplikaciu neukoncilo a ani samotnu proceduru v ktorej som to volal (nav…
Andrej 23.06.2006 01:40
Andrej
Oprava: Exit vykonavanie procedury skutocne zastavi (nevsimol som si pred tym ze som bol este v inej…
Andrej 23.06.2006 01:59
Andrej
Tá diskusia bola na ICQ, ale okrajovo som ten Abort, čo vyhodil chybu spomenul tu: SubChild.asp Edi…
msx. 23.06.2006 14:01
msx.
Bacha na to! Když tady uvedeš odkaz do Big Brothera, tak to tam okamžitě M.L. zuřivě smaže :-D
Remca 23.06.2006 14:55
Remca
Veď práve preto chcem všetky moje programovacie otázky vycucať skôr ako bude neskoro.
msx. 24.06.2006 14:07
msx.
Application.Terminate je korektné ukončenie programu. Ja mám skôr pocit, že tento riadok sa nevykoná…
msx. 22.06.2006 22:29
msx.
Ak uz chces program ukoncit tak pouzi procedurku Halt. Je to sice nasilne ukoncenie, ale co uz... mn…
Intex 23.06.2006 16:07
Intex
Halt:i: je presne to co som chcel od zaciatku. Dokaze to ukoncit priamo vo funkcii kde nacitavam dat…
Andrej 23.06.2006 16:49
Andrej
Ale Halt; si po sebe neuprace. Korektné je len Application.Terminate;. Halt je na použitie vhodný vt…
msx. 24.06.2006 14:06
msx.
Co sa mysli pod? Halt; si po sebe neuprace
Andrej 25.06.2006 00:50
Andrej
To je logické. HALT prostě ustřelí aplikacei a basta fidli, ani programátor nemá šanci uvolnit objek… poslední
Rce 25.06.2006 01:04
Rce

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:

repeat
   try
      HandleMessage;
   except
      HandleException(Self);
   end;
until Terminated;

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.

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

if podmienka je splnena then begin Application.Terminate; Exit; end;

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.

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.

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.

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).

Zpět do poradny Odpovědět na původní otázku Nahoru