Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Delphi
Jak spustit program a počkat na jeho ukončení - podruhé
27. prosince 2001, 00.00 | Podruhé se vracíme k tématu, naznačeném v titulku. Tedy jak spustit ze svého programu jiný program a pak detekovat kdy se ukončí. Tentokrát ale do hry zapojíme multithreading.
V srpnu vyšel na Builderu můj článek o tom, jak spustit ze svého programu jiný program a pak detekovat, kdy se ukončí. Pokud si článek přečtete (což rozhodně doporučuji, jinak nejspíš v tomto článku nebudete úplně v kontextu), zjistíte, že jsme při tvorbě aplikace použili Win32 API funkci WaitForSingleObject, která čekala dokud program neskončil. Problémem ovšem bylo, jak mezitím přinutit aplikaci reagovat na zprávy zasílané Windows - například o nutnosti překreslit okno. Řešení, které jsem použil, bylo z těch méně čistých - spočívalo rozdělení čekání na 100ms intervaly, přičemž mezi každými takovými intervaly se zavolala procedura Application.ProcessMessages, která provedla potřebné ošetření zpráv.
V komentářích pod článkem se objevil mimo jiné i návrh použít v aplikaci vlákna (thready). Jelikož považuji tento nápad za dobrý, podíváme se v tomto článku právě na možnost začlenění vláken do aplikace z minulého článku.
Dva přístupyVlákna by se dala do aplikace začlenit dvěma způsoby:
- Celou implementaci vláken skrýt do volání procedury WinExecAndWait z původní verze programu, která by vrátila až po skončení vlákna otevírajícího spouštěný program. Tím pádem by "vnějšek" programu mohl zůstat stejný, ale na druhou stranu by hlavní vlákno zůstalo zablokováno po dobu, kdy by byl otevřený spuštěný program. Program by se ve výsledku choval v podstatě stejně jako předtím.
- Druhý přístup je proceduru WinExecAndWait nahradit celou vláknem, které by se spustilo, a program by dál pokračoval v normální činnosti. Po skončení vlákna by se zavolala jeho procedura pověšená na jeho události OnTerminate, ve které bychom enablovali ovládací prvky a připravili tak naši aplikaci na spuštění dalšího programu. Výhodou tohoto přístupu je snadnější implementace, ovšem za cenu změnění volání (je nutné přímo v programu vytvořit nové vlákno a nastavit mu některé parametry).
Schémata práce programu v obou případech shrnují následující dva obrázky:
ImplementaceRozhodl jsem se implementovat druhý způsob, protože lépe ukazuje mutithreading v praxi, navíc mi připadá o něco čistší. Unita s vláknem bude vypadat takto:
|
Jak je vidět, hlavní procedura vlákna značně připomíná předchozí WinExecuteAndWait, jen parametry jsou předávány jako pole (ve významu fields, ne array!) objektu vlákna.
Nyní hlavní procedura našeho programu, reagující na stisk tlačítka Spustit:
|
No a nakonec ještě výpis procedury OnThreadTerminate, která se vykoná po skončení činnosti vlákna:
|
Povšimněte si, že objekt vlákna ET je deklarovaný jen jako lokální proměnná. To si můžeme dovolit ze dvou důvodů:
- Je to de facto jen ukazatel na objekt, když procedura skončí a ukazatel se odalokuje, neznamená to, že objekt už také neexistuje.
- Vláknu jsme nastavili vlastnost FreeOnTerminate na True, což zajistí, že po ukončení běhu vlákna se jeho objekt "sám od sebe" odalokuje. Nebudeme tedy nikdy volat ET.Free a nemusíme si tím pádem ET pamatovat.
Fakt že ET je deklarována lokálně navíc teoreticky umožňuje naši aplikaci snadno rozšířit o funkci volání více programů najednou.
ZávěrNyní už máte k dispozici celkem dva způsoby, jak zajistit detekci ukončení spuštěného programu. Je na vás, který se vám bude do vaší aplikace víc hodit.
Můžete si stáhnout kompletní ukázkovou aplikaci i se zdrojáky pro Delphi 3 a vyšší.
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007