Sdílet prostřednictvím


The Workflow Way: Understanding Windows Workflow Foundation

David Chappell
Chappell & Associates

Duben, 2009

Stáhnout tento článek

Představujeme Windows Workflow Foundation

Každý, kdo píše kód, chce vytvářet skvělý software. Pokud je tento software serverovou aplikací, je součástí toho, že je skvělý, dobře škálovat a zpracovávat velké zatížení, aniž by spotřebováváte příliš mnoho prostředků. Skvělá aplikace by také měla být co nejsnadněji srozumitelná, a to jak pro její tvůrce, tak pro lidi, kteří ji udržují.

Dosažení obou těchto cílů není snadné. Přístupy, které pomáhají aplikacím škálovat, je obvykle rozdělují a rozdělují jejich logiku do samostatných bloků, kterým může být obtížné porozumět. Pokud ale napíšete jednotnou logiku, která se nachází v jednom spustitelném souboru, škálování aplikace může být úplně nemožné. To, co je potřeba, je způsob, jak udržet logiku aplikace sjednocenou, aby byla srozumitelnější a aby se aplikace stále škálovala.

Dosažení tohoto cíle je primárním cílem Windows Workflow Foundation (WF). Díky podpoře logiky vytvořené pomocí pracovních postupů poskytuje WF základ pro vytváření jednotných a škálovatelných aplikací. Kromě toho může WF zjednodušit i další výzvy v oblasti vývoje, jako je koordinace paralelní práce, sledování provádění programu a další.

WF byla poprvé vydána s rozhraním .NET Framework 3.0 v roce 2006 a poté aktualizována v rozhraní .NET Framework 3.5. Tyto první dvě verze byly užitečné, zejména pro nezávislé výrobce softwaru, ale pro podnikové vývojáře se nestaly běžnými technologiemi. U verze WF, která je součástí rozhraní .NET Framework 4, se tvůrci snaží toto nastavení změnit. Hlavním cílem této nejnovější verze je učinit WF standardní součástí programovací sady nástrojů pro všechny vývojáře .NET.

Stejně jako každá technologie vyžaduje použití WF pochopení, co to je, proč je užitečné a kdy má smysl ho používat. Cílem tohoto přehledu je tyto věci objasnit. Nenaučíte se psát aplikace WF, ale dozvíte se, co WF nabízí, proč to tak je a jak může zlepšit život vývojářů. Jinými slovy, začnete rozumět způsobu pracovního postupu.

Výzva: Psaní sjednocené a škálovatelné aplikační logiky

Jedním z jednoduchých způsobů, jak napsat program, je vytvořit jednotnou aplikaci, která běží v jednom procesu na jednom počítači. Obrázek 1 znázorňuje tuto myšlenku.

Obrázek 1: Logiku aplikace je možné vytvořit jako jednotný celek a pak spustit v určitém vlákně v procesu běžícím na jednom počítači.

Jednoduchý pseudokód v tomto příkladu ukazuje typy věcí, které aplikace obvykle dělají:

  • Udržovat stav, který je zde reprezentován jednoduchou řetězcovou proměnnou.
  • Získejte vstup z vnějšího světa, například přijetím požadavku od klienta. Jednoduchá aplikace může jen číst z konzoly, zatímco běžnější příklad může obdržet požadavek HTTP z webového prohlížeče nebo zprávu SOAP z jiné aplikace.
  • Odeslání výstupu do vnějšího světa V závislosti na tom, jak je aplikace sestavená, to může provést prostřednictvím protokolu HTTP, zprávy SOAP, zápisem do konzoly nebo jiným způsobem.
  • Zajistěte alternativní cesty prostřednictvím logiky pomocí příkazů toku řízení, jako jsou if/else a while.
  • Pracujte tak, že v každém bodě aplikace spustíte příslušný kód.

V rámci zde uvedeného sjednoceného přístupu tráví logika aplikace celý svůj život běžícím na vlákně uvnitř konkrétního procesu na jednom počítači. Tento jednoduchý přístup má několik výhod. Logiku je možné implementovat přímočarým a jednotným způsobem. To pomáhá uživatelům, kteří pracují s kódem, porozumět tomuto kódu a také to z explicitního pořadí povolených událostí. Například na obrázku 1 je zřejmé, že první požadavek klienta musí předcházet druhému – tok řízení programu to vyžaduje. Když přijde druhý požadavek, není potřeba kontrolovat, jestli už byl první požadavek zpracován, protože neexistuje žádná jiná cesta přes aplikaci.

Další výhodou tohoto přístupu je snadná práce se stavem aplikace. Tento stav je uložen v paměti procesu, a protože proces běží nepřetržitě, dokud se jeho práce nedokončí, je stav vždy k dispozici: Vývojář pouze přistupuje k běžným proměnným. Co by mohlo být jednodušší?

Přesto má tento základní styl programování omezení. Když aplikace potřebuje počkat na vstup, ať už od uživatele v konzole, klienta webových služeb nebo něco jiného, obvykle se jednoduše zablokuje. Vlákno i proces, který používá, se budou uchovávat, dokud se vstup nedorazí, jak dlouho to trvá. Vzhledem k tomu, že vlákna a procesy jsou relativně málo prostředků, aplikace, které se drží jednoho z nich, když jen čekají na vstup, se moc dobře neškálí.

Škálovatelným přístupem je vypnout aplikaci, když čeká na vstup, a pak ji restartovat, až tento vstup přijde. Tento přístup neplýtvat prostředky, protože aplikace nedrží vlákno nebo proces, když je nepotřebuje. Tím také umožníte, aby aplikace běžela v různých procesech na různých počítačích v různých časech. Místo toho, aby byla uzamčena na jeden systém, jak je znázorněno na obrázku 1, může být aplikace spuštěna na jednom z několika dostupných počítačů. To také pomáhá škálovatelnosti, protože práce může být snadněji rozložena do různých počítačů. Obrázek 2 ukazuje, jak to vypadá.

Obrázek 2: Logiku aplikace je možné rozdělit na bloky dat, které sdílejí společný stav, které se můžou spouštět na různých počítačích.

Tato ukázková aplikace obsahuje stejnou logiku jako předtím, ale teď je rozdělená na samostatné bloky dat. Při přijetí prvního požadavku klienta se načte a spustí příslušný blok dat. Jakmile je tento požadavek zpracován a odpověď odeslána zpět, může být tento blok dat uvolněn – nic nemusí zůstat v paměti. Když přijde druhý požadavek klienta, načte se a spustí blok dat, který ho zpracovává. Jak ukazuje obrázek 2, tento blok dat se může spustit v jiném vlákně v jiném procesu spuštěném na jiném počítači od prvního bloku dat. Po zpracování požadavku je možné tento druhý blok dat také uvolnit a uvolnit tak paměť, která používala.

Jedním z běžných příkladů technologie, která funguje tímto způsobem, je ASP.NET. Vývojář implementuje ASP.NET aplikaci jako sadu stránek, z nichž každá obsahuje určitou část logiky aplikace. Po přijetí požadavku se načte, spustí se správná stránka a pak se znovu uvolní.

Aplikace sestavená v tomto stylu může využívat prostředky počítače efektivněji než aplikace vytvořená pomocí jednoduššího přístupu uvedeného výše, takže se škáluje lépe. Přesto jsme zaplatili za tuto vylepšenou škálovatelnost se složitostí. Z jedné věci musí různé bloky kódu nějakým způsobem sdílet stav, jak je znázorněno na obrázku 2. Vzhledem k tomu, že se každý blok dat načítá na vyžádání, spustí se a pak vypne, musí být tento stav uložen externě, například v databázi nebo jiném úložišti trvalosti. Vývojář teď místo přístupu k běžným proměnným, jako je scénář znázorněný na obrázku 1, musí udělat speciální věci, aby získal a uložil stav aplikace. Například v ASP.NET aplikacích můžou vývojáři zapisovat stav přímo do databáze, přistupovat k objektu relace nebo použít jiný přístup.

Dalšími náklady na tuto vylepšenou škálovatelnost je, že kód už neposkytuje jednotný pohled na celkovou logiku programu. Ve verzi znázorněné na obrázku 1 je pořadí, ve kterém program očekává vstup, zřejmé – existuje pouze jedna možná cesta kódem. U verze obrázku 2 ale tento tok řízení není zřejmý. Ve skutečnosti může být nutné, aby blok kódu, který zpracovává druhý požadavek klienta, začal kontrolou, že první požadavek již byl dokončen. Pro aplikaci, která implementuje jakýkoli druh významných obchodních procesů, může být pochopení a správná implementace toku řízení v různých blocích náročná.

Situace je taková: Psaní jednotných aplikací usnadňuje vývojáři život a kód je srozumitelný, ale výsledek se dobře škáluje. Psaní chudších aplikací, které sdílejí externí stav, jako jsou aplikace ASP.NET, umožňuje škálovatelnost, ale ztěžuje správu stavu a ztrácí jednotný tok řízení. Chtěli bychom vytvořit škálovatelnou obchodní logiku s jednoduchou správou stavu, ale přesto mít jednotný přehled o toku řízení aplikace.

To je přesně to, co pracovní postup poskytuje. V další části se dozvíte, jak na to.

Řešení: Způsob pracovního postupu

Pochopení toho, jak aplikace WF řeší tyto (a další) problémy, vyžaduje projít si základy fungování WF. Zároveň uvidíme, proč tato technologie může vývojářům v překvapivě velkém počtu případů zlepšit život.

Vytváření logiky sjednocené aplikace

Aplikace založená na pracovních postupech vytvořená pomocí WF dělá stejné věci jako běžná aplikace: udržuje stav, získává vstup z vnějšího světa a odesílá výstup do vnějšího světa, poskytuje tok řízení a spouští kód, který provádí práci aplikace. V pracovním postupu WF jsou ale všechny tyto věci prováděny aktivitami. Obrázek 3 ukazuje, jak to vypadá, s jednotným kódem zobrazeným společně s porovnáním.

Obrázek 3: V pracovním postupu WF je veškerá práce programu prováděna aktivitami.

Jak ukazuje obrázek 3, každý pracovní postup má vnější aktivitu, která obsahuje všechny ostatní. V tomto případě se tato nejkrajnější aktivita nazývá Sekvence a stejně jako běžný program může mít proměnné, které si zachovávají svůj stav. Vzhledem k tomu, že sequence je složená aktivita, může obsahovat i jiné aktivity.

V tomto jednoduchém příkladu pracovní postup začíná aktivitou ReceiveMessage, která získává vstup z vnějšího světa. Následuje aktivita If, která (nepřekvapí) implementaci větve. Pokud je také složená aktivita obsahující další aktivity (zde označené X a Y), které provádějí práci prováděnou v každé větvi. Za aktivitou If následuje aktivita SendMessage, která odesílá výstup do světa mimo tento pracovní postup. Další aktivita ReceiveMessage se zobrazí jako další, která získá další vstup a pak je následována aktivitou While. Zatímco obsahuje další aktivitu, Z, která dělá práci této smyčky While. Celý pracovní postup končí poslední aktivitou SendMessage, která odešle konečný výsledek programu.

Všechny tyto aktivity funkčně odpovídají různým částem typického programu, jak naznačují odpovídající barvy na obrázku 2. Ale místo použití předdefinovaných jazykových prvků, jak to dělá tradiční program, každá aktivita v pracovním postupu WF je ve skutečnosti třída. Spuštění pracovního postupu provádí modul runtime WF, komponenta, která ví, jak spouštět aktivity. Obrázek 4 znázorňuje tuto myšlenku.

Obrázek 4: Modul runtime WF provádí aktivity v pořadí určeném pracovním postupem.

Když spustí pracovní postup, modul runtime WF nejprve provede vnější aktivitu, což je v tomto příkladu sekvence. Pak provede první aktivitu uvnitř této, což je ReceiveMessage, následovaná další aktivitou atd. Přesně to, které aktivity se provádějí v konkrétní situaci, závisí na tom, jakou cestou se pracovní postup provede. Například získání jednoho typu vstupu v první aktivitě ReceiveMessage může způsobit, že aktivita If provede aktivitu X, zatímco jiný druh vstupu může způsobit, že provede aktivitu Y. Je to jako každý jiný program.

Je důležité si uvědomit, že modul runtime WF vůbec nic neví o interních aktivitách, které provádí. Nemůže zjistit if z ReceiveMessage. Jediné, co ví, jak to udělat, je spustit aktivitu a pak spustit další. Modul runtime ale může zobrazit hranice mezi aktivitami, což je užitečná věc, jak uvidíme.

Důležitým důsledkem je, že WF nedefinuje žádný konkrétní jazyk pro popis pracovních postupů – vše závisí na aktivitách, které se vývojář rozhodne použít. Pro usnadnění života obsahuje WF knihovnu základních aktivit (BAL), která poskytuje široce užitečnou sadu aktivit. (Všechny zde použité ukázkové aktivity jsou ve skutečnosti čerpány z BAL.) Vývojáři ale mohou vytvářet jakékoli další aktivity, které se jim líbí. Dokonce se mohou rozhodnout, že BAL úplně ignorují.

Tady je zjevná otázka: Proč jít do všech těchto potíží? Vytvoření programu pomocí aktivit se liší od toho, na co jsou vývojáři zvyklí, tak proč by se někdo měl obtěžovat? Proč nepsat obyčejný kód?

Odpověď je samozřejmě taková, že tento přístup nám může pomoct vytvořit lepší kód. Všimněte si například, že způsob pracovního postupu dává vývojáři jednotný tok řízení. Stejně jako v jednoduchém případě zobrazeném na obrázku 1 je hlavní logika programu definována v jednom koherentním proudu. To usnadňuje pochopení, a protože logika není rozdělená na bloky dat, není potřeba provádět žádné další kontroly. Samotný pracovní postup vyjadřuje povolený tok řízení.

To představuje polovinu našeho cíle: vytvoření jednotné logiky aplikace. Ale aplikace WF mohou také dosáhnout druhé poloviny a vytvářet škálovatelné aplikace s jednoduchou správou stavu. Další část vysvětluje, jak to způsob pracovního postupu umožňuje.

Zajištění škálovatelnosti

Aby byla škálovatelná, serverovou aplikaci nelze na jednom počítači uzamknout do jednoho procesu. Explicitní rozdělení aplikační logiky na bloky dat, jako na ASP.NET stránkách, ale rozděluje to, co by mělo být jednotným tokem řízení. To také nutí programátor pracovat se stavem explicitně. To, co bychom opravdu chtěli, je způsob, jak naši logiku automaticky rozdělit na bloky dat, které se můžou spouštět v různých procesech na různých počítačích. Také bychom chtěli, aby se stav naší aplikace spravil za nás, takže stačí přistupovat k proměnným.

Přesně to pracovní postupy poskytují. Obrázek 5 ukazuje základní informace o tom, jak WF tyto věci dosahuje.

Obrázek 5: Modul runtime WF uvolní pracovní postup, zatímco čeká na vstup, a po přijetí vstupu ho znovu načte.

Stejně jako každá aplikace blokuje pracovní postup WF čekání na vstup. Například na obrázku 5 je pracovní postup zablokovaný při druhé aktivitě ReceiveMessage, která čeká na druhý požadavek klienta (krok 1). Modul runtime WF si toho všimne, a proto ukládá stav pracovního postupu a údaj o tom, kde se má pracovní postup v úložišti trvalosti pokračovat (krok 2). Když pro tento pracovní postup přijde vstup (krok 3), modul runtime WF najde svůj trvalý stav a pak pracovní postup znovu načte a provede provádění tam, kde skončil (krok 4). Všechno se děje automaticky – vývojář WF nemusí nic dělat. Vzhledem k tomu, že modul runtime WF může vidět do pracovního postupu, může všechny tyto podrobnosti zpracovat sám.

Jednou ze zřejmých výhod tohoto přístupu je, že pracovní postup neblokuje vlákno v paměti a nevyužívá proces, zatímco čeká na vstup. Další výhodou je, že trvalý pracovní postup může být potenciálně znovu načten na jiném počítači, než na kterém byl původně spuštěný. Z tohoto důvodu můžou různé části pracovního postupu nakonec běžet v různých systémech, jak je znázorněno na obrázku 6.

Obrázek 6: Pracovní postup může běžet v různých vláknech, v různých procesech a na různých počítačích během své životnosti.

V tomto příkladu předpokládejme, že pracovní postup zpracovává první požadavek klienta v procesu na počítači A. Když druhá ReceiveMessage způsobí, že pracovní postup blokuje čekání na vstup, modul runtime WF uvolní stav pracovního postupu do úložiště trvalosti, jak je právě popsáno. Když přijde druhý požadavek klienta, je možné tento pracovní postup znovu načíst do procesu na počítači B. Pracovní postup WF je možné podle potřeby přesunout do určitého vlákna v konkrétním procesu. A vývojář získá tuto flexibilitu zdarma – poskytuje ji automaticky WF.

Je vhodné poznamenat, že modul runtime WF se nezajímá, jak dlouho musí pracovní postup čekat na vstup. Může dorazit několik sekund po zachování pracovního postupu, o několik minut později nebo dokonce o několik měsíců později. Pokud úložiště trvalosti stále drží stav pracovního postupu, je možné tento pracovní postup restartovat. Díky tomu je WF atraktivní technologií pro vytváření aplikací, které implementují dlouhotrvající procesy. Představte si například aplikaci podporující náborový proces, který zahrnuje vše od plánování počátečních pohovorů až po integraci nového zaměstnance do organizace. Tento proces může trvat týdny nebo měsíce, takže správa stavu aplikace pomocí WF dává dobrý smysl. I když může být WF u tohoto typu dlouhotrvajícího procesu docela užitečný, je důležité si uvědomit, že to není jeho jediný účel. Vhodným kandidátem pro WF může být jakákoli aplikace, která vyžaduje jednotnou a škálovatelnou logiku.

Ve skutečnosti se podívejte na obrázek 6. Nevypadá to příliš jako na obrázku 2, který ukazuje, jak aplikace s velkým objemem dat (například aplikace sestavená výhradně s ASP.NET) dosáhla škálovatelnosti? A ve skutečnosti nemá obrázek 6 také silnou podobnost s obrázkem 1, který ukazuje jednotnou aplikaci vytvořenou s lineárním řídicím tokem? WF dosahuje obou těchto věcí: Tok řízení aplikace je vyjádřen srozumitelným a jednotným způsobem a aplikace se může škálovat, protože není uzamčena na jeden proces na jednom počítači. To je krása pracovního postupu.

A to není vše. použití WF má také další výhody. Může usnadnit koordinaci paralelní práce, například pomoc se sledováním průběhu aplikace a další. V další části se podíváme na tyto aspekty technologie.

Další výhody způsobu pracovního postupu

Pracovní postup WF se skládá z aktivit spuštěných modulem runtime WF. I když pochopení světa WF vyžaduje určité úsilí, psaní aplikační logiky v tomto stylu usnadňuje řadu běžných programovacích výzev, jak je popsáno dále.

Koordinace paralelní práce

WF BAL zahrnuje aktivity, které odpovídají známým příkazům programovacího jazyka. Z tohoto důvodu můžete psát pracovní postupy, které se chovají podobně jako běžné programy. Přítomnost modulu runtime WF ale také umožňuje vytvářet aktivity, které poskytují více než běžný programovací jazyk. Důležitým příkladem je použití pracovního postupu, který usnadňuje koordinaci paralelní práce.

Nenechte se zmást: V této části se nezaměřujte na psaní paralelního kódu, který běží současně na vícejádrových procesorech. Místo toho se zamyslete nad aplikací, která potřebuje volat dvě webové služby, a pak počkejte na oba výsledky, než budete pokračovat. Paralelní provádění volání je jasně rychlejší než jejich postupné provádění, ale psaní tradičního kódu, který to dělá, není jednoduché. A zatímco rozhraní .NET Framework poskytuje různé přístupy k provádění těchto volání asynchronně, žádný z nich není zvlášť jednoduchý. To je další situace, ve které může pracovní postup zářit: WF to usnadňuje. Obrázek 7 ukazuje postup.

Obrázek 7: Aktivity obsažené v paralelní aktivitě běží paralelně.

Tento obrázek znázorňuje jednoduchý pracovní postup, který se podobá předchozímu příkladu. Velký rozdíl spočívá v tom, že teď vyvolá dvě webové služby a pak čeká na odpověď z obou, než bude pokračovat. Chcete-li provést tato volání paralelně, tvůrce pracovního postupu zabalil obě dvojice SendMessage a ReceiveMessage aktivity uvnitř paralelní aktivity. Parallel je standardní součástí knihovny základních aktivit WF a dělá přesně to, co jeho název naznačuje: paralelně provádí aktivity, které obsahuje. Místo toho, aby se vývojáři zabývali složitostí tohoto zpracování, modul runtime WF a paralelní aktivita dělají těžké zvedání. Vše, co vývojář musí udělat, je uspořádat aktivity podle potřeby, aby vyřešil svůj problém.

Poskytování automatického sledování

Vzhledem k tomu, že modul runtime WF vidí hranice mezi aktivitami pracovního postupu, ví, kdy každá z těchto aktivit začíná a končí. Vzhledem k tomu je poskytování automatického sledování provádění pracovního postupu jednoduché. Tuto myšlenku znázorňuje obrázek 8.

Obrázek 8: Modul runtime WF může automaticky sledovat provádění pracovního postupu.

Jak ukazuje tento příklad, modul runtime WF může zapsat záznam o spuštění pracovního postupu do úložiště sledování. Jednou z možností je protokolování aktivit, přičemž záznam se zapíše pokaždé, když aktivita začne a ukončí provádění. V tuto chvíli je na obrázku například pracovní postup, který se chystá zahájit provádění aktivity If, a proto modul runtime WF zapisuje událost, která tuto událost označuje. Je také možné sledovat konkrétní proměnné, tj. stav pracovního postupu, zaznamenávat jejich hodnoty v různých bodech provádění pracovního postupu.

Stejně jako u jiných aspektů WF toto automatické protokolování v podstatě nevyžaduje žádnou práci ze strany vývojáře. Může jenom naznačit, že by mělo dojít ke sledování, určit úroveň, která ho zajímá, a WF se postará o zbytek.

Vytváření opakovaně použitelných vlastních aktivit

Aktivity ve WF BAL poskytují celou řadu užitečných funkcí. Jak už jsme například ukázali, tato integrovaná sada zahrnuje aktivity pro tok řízení, odesílání a přijímání zpráv, paralelní práci a další. Vytvoření skutečné aplikace ale obvykle vyžaduje vytvoření aktivit, které provádějí úlohy specifické pro danou aplikaci.

Aby to bylo možné, WF umožňuje vytváření vlastních aktivit. Například aktivity označené jako X, Y a Z v pracovních postupech zobrazených výše jsou ve skutečnosti vlastní aktivity, jak je znázorněno na obrázku 9.

Obrázek 9: Vlastní aktivity umožňují pracovnímu postupu provádět úlohy specifické pro aplikaci.

Vlastní aktivity můžou být jednoduché, provádějí jenom jeden úkol, nebo se můžou jednat o složené aktivity obsahující libovolně složitou logiku. A bez ohledu na to, jestli jsou jednoduché nebo složité, můžete vlastní aktivity používat mnoha různými způsoby. Například obchodní aplikace vytvořená pomocí WF může implementovat logiku specifickou pro aplikaci jako jednu nebo více vlastních aktivit. Případně může dodavatel softwaru používající WF poskytnout sadu vlastních aktivit, které zákazníkům usnadní život. Windows SharePoint Services například umožňuje vývojářům vytvářet aplikace založené na WF, které komunikují s lidmi prostřednictvím standardních seznamů SharePointu. Aby to bylo jednodušší, SharePoint zahrnuje vlastní aktivity pro zápis informací do seznamu.

Vlastní aktivity je možné psát přímo v kódu pomocí jazyka C#, Visual Basicu nebo jiného jazyka. Mohou být také vytvořeny kombinací existujících aktivit, což umožňuje některé zajímavé možnosti. Organizace může například vytvářet vlastní aktivity nižší úrovně pro své nejzkušenější vývojáře a pak je zabalit do vyšších obchodních funkcí pro méně technické lidi. Tyto aktivity vyšší úrovně můžou implementovat jakoukoli obchodní logiku, která je potřeba, a to vše úhledně zabalené do opakovaně použitelného rámečku.

Dalším způsobem, jak o tom přemýšlet, je zobrazit konkrétní sadu aktivit spouštěných modulem runtime WF jako jazyk. Pokud organizace vytvoří skupinu vlastních aktivit, které je možné znovu použít k řešení konkrétních problémů ve více aplikacích, ve skutečnosti vytváří druh jazyka specifického pro doménu (DSL). Jakmile to uděláte, může být pro méně technické uživatele možné vytvářet aplikace WF pomocí těchto předem zabalených bloků vlastních funkcí. Místo psaní nového kódu pro implementaci funkcí aplikace by užitečný nový software mohl být vytvořen výhradně sestavením existujících aktivit. Tento styl DSL definovaný způsobem pracovního postupu může v některých situacích výrazně zvýšit produktivitu vývojářů.

Zviditelnění procesů

Vytváření aplikací pomocí tradičního programovacího jazyka znamená psaní kódu. Vytváření aplikací pomocí WF obvykle není tak nízké. Místo toho je možné graficky sestavit alespoň hlavní tok řízení pracovního postupu. Aby to bylo možné, WF obsahuje návrháře pracovních postupů, který běží v sadě Visual Studio. Obrázek 10 ukazuje příklad.

Obrázek 10: Návrhář pracovního postupu spuštěný v sadě Visual Studio umožňuje vývojáři vytvořit pracovní postup přetažením aktivit.

Jak ukazuje tento příklad, aktivity dostupné pro vývojáře WF se zobrazí vlevo. Aby mohla vytvořit pracovní postup, může tyto aktivity sestavit na návrhové ploše a vytvořit logiku, jakou aplikace vyžaduje. V případě potřeby může být návrhář pracovních postupů WF také hostovaný v jiných prostředích, aby ostatní mohli tento nástroj používat ve svých vlastních nabídkách.

Pro některé vývojáře tento grafický přístup umožňuje rychlejší a jednodušší vytváření aplikací. To také zviditelňuje hlavní logiku aplikace. Návrhář pracovních postupů WF poskytuje přímočarý přehled o tom, co se děje, a pomůže tak vývojářům rychleji porozumět struktuře aplikace. To může být zvlášť užitečné pro uživatele, kteří musí udržovat nasazené aplikace, protože naučit se novou aplikaci dostatečně dobře změnit, může být časově náročný proces.

Ale co vlastní aktivity? Není ještě potřeba psát kód? Odpověď je ano, a proto WF také umožňuje pomocí sady Visual Studio vytvářet vlastní aktivity v jazyce C#, Visual Basic a dalších jazycích. Abyste pochopili, jak to funguje, je důležité pochopit, jak návrhář WF představuje různé části pracovního postupu. Obrázek 11 ukazuje, jak se to obvykle dělá.

Obrázek 11: Stav a tok řízení pracovního postupu jsou obvykle popsány v XAML, zatímco vlastní aktivity se dají zapsat v kódu.

Složení pracovního postupu WF – aktivity, které obsahuje a jak tyto aktivity souvisejí – je obvykle reprezentováno pomocí jazyka XAML (eXtensible Application Markup Language). Jak ukazuje obrázek 11, XAML poskytuje způsob, jak popsat stav pracovního postupu jako proměnné a vyjádřit vztahy mezi aktivitami pracovního postupu založený na jazyce XML. Například XAML pro nejkrajnější sekvenci aktivit pracovního postupu obsahuje aktivitu ReceiveMessage následovanou aktivitou If, jak byste očekávali.

Tato aktivita If obsahuje vlastní aktivity X a Y. Tyto aktivity se ale nevytvořují v JAZYCE XAML jako třídy jazyka C#. I když je možné vytvořit některé vlastní aktivity výhradně v XAML, specializovanější logika se obvykle píše přímo v kódu. I když to není obvyklý přístup, vývojář může také psát pracovní postupy zcela v kódu – použití XAML není nezbytně nutné.

Použití Windows Workflow Foundation: Některé scénáře

Pochopení mechanismu WF je nezbytnou součástí pochopení způsobu pracovního postupu. To ale nestačí: Musíte také pochopit, jak se pracovní postupy dají v aplikacích používat. V této části se proto architektonicky podíváme na to, jak a proč je možné WF používat v některých typických situacích.

Vytvoření služby pracovního postupu

Vytváření obchodní logiky jako služby často dává smysl. Předpokládejme například, že ke stejné sadě funkcí se musí přistupovat z prohlížeče prostřednictvím ASP.NET, z klienta Silverlightu a ze samostatné desktopové aplikace. Nejlepší přístup bude pravděpodobně implementace této logiky jako sady operací, které lze vyvolat z kteréhokoli z těchto klientů – tedy jako služby. Zveřejnění logiky jako služby také zpřístupňuje ji jiné logice, což může někdy usnadnit integraci aplikací. (Toto je základní myšlenka, která stojí za konceptem SOA, architektury orientované na služby.)

Pro vývojáře .NET je dnes hlavní technologií pro vytváření služeb Windows Communication Foundation (WCF). WCF mimo jiné umožňuje vývojářům implementovat obchodní logiku, která je přístupná pomocí REST, SOAP a dalších komunikačních stylů. A u některých služeb může být WCF vše, co je potřeba. Pokud například implementujete službu, ve které každá operace stojí samostatně – libovolnou operaci je možné kdykoli volat bez požadovaného pořadí – sestavení těchto služeb jako nezpracovaných služeb WCF je v pořádku. Tvůrce služby, jejíž operace pouze zpřístupňují data, může být například schopen projít jenom pomocí WCF.

V složitějších situacích, kdy operace ve službě implementují související sadu funkcí, nemusí samotný WCF stačit. Zamyslete se nad aplikacemi, které zákazníkům umožňují rezervovat si letenky, nakupovat online nebo provádět jiný obchodní proces. V takových případech se můžete rozhodnout použít WF k implementaci logiky služby. Tato kombinace má dokonce název: Logika implementovaná pomocí WF a vystavená prostřednictvím WCF se označuje jako služba pracovního postupu. Obrázek 12 znázorňuje tuto myšlenku.

Obrázek 12: Služba pracovního postupu používá WCF ke zveřejnění logiky založené na WF.

Jak ukazuje obrázek, WCF umožňuje odhalit jeden nebo více koncových bodů, které můžou klienti volat prostřednictvím protokolu SOAP, REST nebo něčeho jiného. Když klient zavolá počáteční operaci v této ukázkové službě, požadavek zpracuje první aktivita ReceiveMessage pracovního postupu. Aktivita If se zobrazí jako další a která z jejích obsažených vlastních aktivit se provede, závisí na obsahu požadavku klienta. Po dokončení if je odpověď vrácena přes SendMessage. Druhý požadavek klienta, vyvolání jiné operace, je zpracován podobným způsobem: Přijímá ho ReceiveMessage, zpracovává logika pracovního postupu a pak odpovídá pomocí SendMessage.

Proč je vytváření obchodní logiky orientované na služby tímto způsobem dobrý nápad? Odpověď je nasnadě: Umožňuje vytvořit jednotnou a škálovatelnou aplikaci. Místo toho, aby každá operace obsahovala kontroly – je legální mě hned vyvolat? – jsou tyto znalosti vložené do samotné logiky pracovního postupu. To usnadňuje psaní aplikace a stejně důležité je srozumitelnější pro lidi, kteří ji nakonec musí udržovat. A místo psaní vlastního kódu pro zpracování škálovatelnosti a správy stavu dělá modul runtime WF tyto věci za vás.

Služba pracovního postupu také získá všechny výhody popsané výše, stejně jako jakákoli jiná aplikace WF. Mezi ně patří:

  • Implementace služeb, které provádějí paralelní práci, je jednoduchá: stačí převést aktivity do paralelní aktivity.
  • Sledování zajišťuje modul runtime.
  • V závislosti na doméně problému může být možné vytvořit opakovaně použitelné vlastní aktivity pro použití v jiných službách.
  • Pracovní postup lze vytvořit graficky, přičemž logika procesu je přímo viditelná v návrháři pracovního postupu WF.

Použití WF a WCF společně – vytváření služeb pracovních postupů – nebylo v dřívějších verzích WF tak snadné. S rozhraním .NET Framework 4 se tato kombinace technologií spojuje přirozeněji. Cílem je, aby vytváření obchodní logiky v tomto stylu bylo co nejjednodušší.

Spuštění služby pracovního postupu s "Dublinem"

Jeden velký problém s pracovními postupy ještě nebyl diskutován: Kde se spouští? Modul runtime WF je třída, stejně jako aktivity. Všechny tyto věci musí běžet v nějakém hostitelském procesu, ale o jaký proces se jedná?

Odpověď je, že pracovní postupy WF můžou běžet v podstatě v jakémkoli procesu. Můžete si vytvořit vlastního hostitele, a pokud chcete, můžete dokonce nahradit některé základní služby WF (jako je trvalost). Udělala to spousta organizací, zejména dodavatelé softwaru. Vytvoření skutečně funkčního hostitelského procesu pro WF s možnostmi správy ale není nejjednodušší na světě. A pro organizace, které chtějí utrácet své peníze na budování obchodní logiky místo infrastruktury, dává smysl vyhnout se tomuto úsilí.

Jednodušší možností je hostovat pracovní postup WF v pracovním procesu poskytovaném internetovou informační službou (IIS). I když to funguje, poskytuje pouze holé kosti-řešení. Aby se vývojářům WF usnadnil život, microsoft poskytuje technologii s kódem s názvem Dublin. Implementované jako rozšíření služby IIS a Aktivační služby procesů systému Windows (WAS), primárním cílem "Dublinu" je zatraktivnit služby IIS a WAS jako hostitele pro služby pracovních postupů. Obrázek 13 ukazuje, jak vypadá služba pracovního postupu, když běží v prostředí "Dublin".

Obrázek 13: Dublin poskytuje správu a další možnosti pro služby pracovních postupů.

I když WF sám o sobě zahrnuje mechanismy pro zachování stavu pracovního postupu, sledování a další, poskytuje pouze základní informace. Dublin staví na vnitřní podpoře WF a nabízí plně užitečnější a spravovatelné prostředí. Například spolu s úložištěm trvalosti založeným na SQL Server a úložištěm sledování poskytuje "Dublin" nástroj pro správu pro práci s těmito obchody. Tento nástroj, který je implementovaný jako rozšíření Správce služby IIS, umožňuje uživatelům zkoumat a spravovat (např. ukončit) trvalé pracovní postupy, řídit, kolik sledování se provádí, zkoumat protokoly sledování a další.

Kromě svých stávajících funkcí WF "Dublin" přidává i další služby. Například "Dublin" může monitorovat spuštěné instance pracovního postupu a automaticky restartovat všechny, které selžou. Primární cíl Microsoftu v rámci "Dublinu" je jasný: poskytování užitečné sady nástrojů a infrastruktury pro správu a monitorování služeb pracovních postupů hostovaných ve službě IIS/WAS.

Použití služby pracovního postupu v aplikaci ASP.NET

Je pravděpodobně spravedlivé říci, že většina aplikací .NET používá ASP.NET. Vytvoření hlavního pracovního postupu znamená, že WF bude atraktivní volbou pro ASP.NET vývojáře.

V dřívějších verzích WF nebyl výkon pracovního postupu dostatečně dobrý pro velký počet ASP.NET aplikací. Pro verzi .NET Framework 4 však návrháři WF přepracovali důležité části technologie, což výrazně zvýšilo výkon. Díky této verzi, spolu s nástupem "Dublinu", jsou aplikace založené na WF – zejména služby pracovních postupů – vhodnější možností pro ASP.NET vývojáře. Obrázek 14 ukazuje jednoduchý obrázek toho, jak to vypadá.

Obrázek 14: Obchodní logiku ASP.NET aplikace je možné implementovat jako službu pracovního postupu

V tomto scénáři ASP.NET stránky implementují pouze uživatelské rozhraní aplikace. Jeho logika se implementuje zcela ve službě pracovního postupu. Pro službu pracovního postupu je aplikace ASP.NET jen dalším klientem, zatímco u ASP.NET aplikace vypadá služba pracovního postupu jako jakákoli jiná služba. Nemusí vědět, že se tato služba implementuje pomocí WF a WCF.

I když znovu, velká otázka je: Proč byste to udělali? Proč prostě nenapsat logiku ASP.NET aplikace obvyklým způsobem? Co vám používání WF (a WCF) koupí? V tomto okamžiku je většina odpovědí na tyto otázky pravděpodobně jasná, ale přesto stojí za to:

  • Místo toho, aby se logika aplikace rozprostřela na mnoho různých ASP.NET stránek, může být tato logika implementována v rámci jednoho jednotného pracovního postupu. Zvláště u velkých webů to může výrazně usnadnit sestavování a údržbu aplikace.
  • Místo toho, aby vývojář explicitně pracoval se stavem v aplikaci ASP.NET, například pomocí objektu Session nebo něčeho jiného, může k tomu spoléhat na modul runtime WF. Aplikace ASP.NET potřebuje sledovat pouze identifikátor instance pro každou instanci pracovního postupu (pravděpodobně jeden na uživatele), například jeho uložením do souboru cookie. Když aplikace poskytne tento identifikátor do "Dublin", instance pracovního postupu se automaticky znovu načte. Pak začne s prováděním tam, kde skončil, s obnovením veškerého stavu.
  • Platí i další výhody WF, mezi které patří jednodušší paralelismus, integrované sledování, potenciál opakovaně použitelných aktivit a schopnost vizualizovat logiku aplikace.

Vzhledem k tomu, že služba pracovního postupu není svázaná s konkrétním procesem na konkrétním počítači, je možné vyrovnává zatížení napříč několika "dublinovými" instancemi. Obrázek 15 ukazuje příklad, jak to může vypadat.

Obrázek 15: Replikovaná aplikace ASP.NET může ke spuštění služby pracovního postupu používat několik "dublinských" instancí.

V tomto jednoduchém scénáři se stránky ASP.NET aplikace replikují do tří serverových počítačů služby IIS. Zatímco tyto stránky zpracovávají interakci s uživateli, obchodní logika aplikace se implementuje jako služba pracovního postupu spuštěná s "Dublinem". Jsou spuštěné dvě instance dublinského prostředí, každá na vlastním počítači. Když přijde první požadavek od uživatele, nástroj pro vyrovnávání zatížení ho nasměruje do nejvyšší instance služby IIS. Stránka ASP.NET, která zpracovává tento požadavek, volá operaci ve službě pracovního postupu, která implementuje tento blok obchodní logiky. To způsobí, že pracovní postup WF se začne spouštět v instanci "Dublin" na horním počítači na obrázku. Po dokončení příslušných aktivit v tomto pracovním postupu se volání vrátí na stránku ASP.NET a pracovní postup se zachová.

Druhý požadavek uživatele se přesměruje do jiné instance služby IIS. Stránka ASP.NET na tomto počítači zase vyvolá operaci v (trvalém) pracovním postupu na jiném počítači, než který vyřídil její první požadavek. To není žádný problém: Dublin načte instanci pracovního postupu z úložiště trvalosti, které sdílí se svým dalším serverem. Tato znovu načtená služba pracovního postupu pak zpracuje požadavek uživatele a přejde tam, kde skončila.

Pochopení WF (a WCF) a následné učení vytváření logiky v tomto novém stylu vyžaduje trochu práce. V případě jednoduchých ASP.NET aplikací nemusí být přechod na tuto křivku učení za to, co je potřeba. Každý, kdo vytváří větší webové aplikace pomocí .NET, by však měl alespoň zvážit možnost vytvoření své logiky jako služby pracovních postupů.

Použití pracovních postupů v klientských aplikacích

Zatím se výhradně zaměřujeme na vytváření serverových aplikací pomocí WF. I když se dnes tato technologie nejčastěji používá, může být WF užitečná i pro klientské aplikace. Jeho aspekty škálovatelnosti v tomto případě obvykle příliš nepřidá, protože kód, který běží na klientských počítačích, obvykle nemusí zpracovávat velké množství souběžných uživatelů, ale WF může být stále k použití.

Představte si například klientskou aplikaci, která uživateli představí grafické rozhraní vytvořené pomocí model Windows Forms nebo Windows Presentation Foundation. Aplikace bude pravděpodobně mít obslužné rutiny událostí, které zpracovávají kliknutí myší uživatele, a možná rozloží obchodní logiku mezi tyto obslužné rutiny událostí. Je to podobné, jako by aplikace ASP.NET rozprostírá svou logiku na skupinu samostatných stránek a může způsobovat stejné výzvy. Tok aplikace může být například obtížné rozpoznat a vývojář může potřebovat vložit kontroly, aby se zajistilo, že se věci provádějí ve správném pořadí. Stejně jako u ASP.NET aplikace může implementace této logiky jako jednotného pracovního postupu WF pomoct tyto problémy vyřešit.

Pro klienta můžou být užitečné i další aspekty WF. Předpokládejme, že aplikace potřebuje paralelně vyvolat více back-endových webových služeb, nebo může těžit ze sledování. Stejně jako na serveru může WF pomoct tyto výzvy vyřešit. I když dnes většina aplikací WF běží na serverech, je důležité si uvědomit, že to není jediná volba.

Bližší pohled: Technologie Windows Workflow Foundation

Cílem tohoto přehledu není udělat z vás vývojáře WF. Znalost technologie WF vám ale může pomoct při rozhodování, kdy má smysl zvolit způsob pracovního postupu. Proto se v této části podrobněji podíváme na některé z nejdůležitějších částí WF.

Druhy pracovních postupů

V rozhraní .NET Framework 4 vývojáři WF obvykle volí mezi dvěma různými styly pracovního postupu volbou různých krajovějších aktivit. Mezi tyto aktivity patří:

  • Posloupnost: Provádí aktivity postupně, jednu po druhé. Sekvence může obsahovat aktivity If, Aktivity While a další druhy toku řízení. Není však možné přejít zpět – provádění se musí vždy posunout dopředu.
  • Vývojový diagram: Provádí aktivity jednu po druhé, například sekvenci, ale umožňuje také návrat řízení k dřívějšímu kroku. Tento flexibilnější přístup, který je novinkou ve verzi WF pro .NET Framework 4, je blíže tomu, jak fungují skutečné procesy, a způsobu, jakým si většina z nás myslí.

Sekvence i vývojový diagram sice můžou fungovat jako nejkrajnější aktivity v pracovním postupu, ale dají se použít i v rámci pracovního postupu. To umožňuje, aby se tyto složené aktivity vnořily libovolnými způsoby.

V prvních dvou verzích WF obsahovala také další možnost pro vnější aktivitu pracovního postupu s názvem State Machine. Jak název napovídá, tato aktivita umožňuje vývojáři explicitně vytvořit stavový počítač a pak na tomto stavovém počítači aktivovat aktivity externích událostí. WF v rozhraní .NET Framework 4 představuje velkou změnu, která však vyžadovala přepsání většiny aktivit v dřívějších verzích a vytvoření nového návrháře. Vzhledem k úsilí, které to s tím spojené, nebudou tvůrci WF doručovat aktivitu State Machine z počáteční verze rozhraní .NET Framework 4. (Ani prostředky Microsoftu nejsou neomezené.) Nová aktivita vývojového diagramu by ale měla řešit řadu situací, které se dříve vyžadovaly při použití stavového počítače.

Knihovna základních aktivit

Pracovní postup může obsahovat libovolnou sadu aktivit, které se vývojář rozhodne použít. Je například zcela legální, aby pracovní postup obsahoval jen vlastní aktivity. Přesto to není moc pravděpodobné. Pracovní postup WF většinou využívá alespoň část toho, co je k dispozici v základní knihovně aktivit. Mezi obecně užitečnější aktivity BAL poskytované WF v rozhraní .NET Framework 4 patří:

  • Přiřadit: Přiřadí hodnotu proměnné v pracovním postupu.
  • Kompenzace: Poskytuje způsob, jak provést kompenzaci, například vyřešit problém, ke kterému dochází v dlouhotrvající transakci.
  • Mezitím: Spustí aktivitu a pak zkontroluje podmínku. Aktivita se bude spouštět dokola, dokud bude podmínka splněná.
  • Vývojový diagram: Seskupuje sadu aktivit, které se provádějí postupně, ale umožňuje také návrat řízení k dřívějšímu kroku.
  • ForEach: Spustí aktivitu pro každý objekt v kolekci.
  • If: vytvoří větev provádění.
  • Paralelní: Spouští více aktivit najednou.
  • Zachovat: Explicitně požádá modul runtime WF o zachování pracovního postupu.
  • Možnost Vybrat: umožňuje počkat na sadu událostí a pak spustit pouze aktivitu přidruženou k první události, která nastane.
  • ReceiveMessage: přijímá zprávu prostřednictvím WCF.
  • SendMessage: Odešle zprávu přes WCF.
  • Posloupnost: seskupuje sadu aktivit, které se provádějí postupně. Kromě toho, že sekvence funguje jako vnější aktivita pracovního postupu, je užitečná také uvnitř pracovních postupů. Například aktivita While může obsahovat pouze jednu další aktivitu. Pokud je tato aktivita Sequence, může vývojář spustit libovolný počet aktivit ve smyčce while.
  • Přepínač: Poskytuje vícecestnou větev provádění.
  • Throw (Hodit): Vyvolá výjimku.
  • TryCatch: Umožňuje vytvořit blok try/catch pro zpracování výjimek.
  • While: spustí jednu aktivitu, pokud podmínka bude true.

Tento seznam není úplný – WF v rozhraní .NET Framework 4 obsahuje další. Společnost Microsoft také plánuje zpřístupnit nové aktivity WF na svém hostitelském webu CodePlex pro open source projekty. Krátce po vydání rozhraní .NET Framework 4 například vyhledejte aktivity, které pracovním postupům umožňují vydávat databázové dotazy a aktualizace, spouštět příkazy PowerShellu a další.

Jak tento seznam naznačuje, BAL do značné míry odráží funkce tradičního programovacího jazyka pro obecné účely. To by nemělo být překvapující, protože WF má být univerzální technologie. Jak je ale popsáno v tomto přehledu, přístup, který používá – aktivity prováděné modulem runtime WF – může někdy zlepšit život vývojářům aplikací.

Pracovní postup v rozhraní .NET Framework 4

Verze 4 rozhraní .NET Framework přináší významné změny do Windows Workflow Foundation. Přepsaly se například aktivity v BAL a přibyly některé nové. To přináší skutečné výhody – mnoho pracovních postupů teď například běží mnohem rychleji, ale také to znamená, že pracovní postupy vytvořené pomocí starších verzí WF nelze spouštět ve verzi .NET 4 modulu runtime WF. Tyto starší pracovní postupy můžou stále běžet společně s pracovními postupy rozhraní .NET Framework 4 beze změny, ale nemusí být zahozeny. Aktivity vytvořené pomocí starších verzí WF, včetně celých pracovních postupů, mohou potenciálně běžet uvnitř nové aktivity zprostředkovatele komunikace, kterou WF v rozhraní .NET Framework 4 poskytuje. To umožňuje použít logiku ze starších pracovních postupů v nových pracovních postupech.

Kromě lepšího výkonu přináší tato nová verze WF také další zajímavé změny. Například dřívější verze WF obsahovaly aktivitu Kódu, která by mohla obsahovat libovolný kód. To vývojáři umožnili přidat do pracovního postupu téměř všechny požadované funkce, ale bylo to poněkud nelegantní řešení. V rozhraní .NET Framework 4 tvůrci WF výrazně zjednodušili psaní vlastních aktivit, a proto byla aktivita Kódu odebrána. Nová funkce se teď vytváří jako vlastní aktivita.

Změny ve verzi .NET Framework 4 jsou nejvýraznější od původního vzhledu WF v roce 2006. Všechny mají ale stejný cíl: usnadnit vývojářům vytváření efektivních aplikací pomocí pracovních postupů.

Závěr

Windows Workflow Foundation nabízí skutečné výhody pro mnoho aplikací. V prvních verzích WF narazilo na strunu hlavně u dodavatelů softwaru. Tyto původní inkarnace této technologie byly užitečné, ale nebyly ve skutečnosti vhodné pro běžné podnikové použití. S rozhraním .NET Framework 4 se tvůrci WF snaží toto nastavení změnit.

Díky tomu, že WF a WCF dobře spolupracují, zlepšují výkon WF, poskytují lepší návrháře pracovních postupů a nabízejí plnohodnotný hostitelský proces s "Dublinem", Microsoft dělá způsob pracovního postupu atraktivnější pro širší škálu scénářů. Jeho dny jako specializovaný hráč v drama vývoje aplikací pro Windows se chýlí ke konci. WF je na cestě do středu pódia.

O autorovi

David Chappell je ředitel společnosti Chappell & Associates v San Franciscu v Kalifornii. Díky svému přednášení, psaní a poradenství pomáhá lidem po celém světě pochopit, používat a lépe se rozhodovat o nových technologiích.