Sdílet prostřednictvím


Úvod vývojáře do Windows Workflow Foundation (WF) v .NET 4

Matt Milner, Pluralsight

Listopad 2009

Aktualizováno na verzi: duben 2010

Přehled

Jak vědí vývojáři softwaru, psaní aplikací může být náročné a neustále hledáme nástroje a architektury, které zjednodušují proces a pomáhají nám soustředit se na obchodní výzvy, které se snažíme vyřešit.  Přešli jsme od psaní kódu v strojových jazycích, jako je assembler, na vyšší úroveň jazyků, jako je C# a Visual Basic, které usnadňují vývoj, odstraňují obavy nižší úrovně, jako je správa paměti, a zvyšují produktivitu jako vývojáři.  Pro vývojáře Microsoftu přechod na .NET umožňuje modulu CLR (Common Language Runtime) přidělovat paměť, vyčistit nepotřebné objekty a zpracovávat konstrukce nízké úrovně, jako jsou ukazatele. 

Velká část složitosti aplikace se nachází v logice a zpracování, které probíhá na pozadí.  Problémy, jako je asynchronní nebo paralelní spouštění a obecná koordinace úloh, které reagují na žádosti uživatelů nebo žádosti o služby, můžou rychle vést vývojáře aplikací zpět do kódování popisovačů, zpětných volání, synchronizace atd. Jako vývojáři potřebujeme stejnou sílu a flexibilitu deklarativního programovacího modelu pro vnitřní prvky aplikace, jaké máme pro uživatelské rozhraní ve Windows Presentation Foundation (WPF). Windows Workflow Foundation (WF) poskytuje deklarativní architekturu pro vytváření logiky aplikací a služeb a poskytuje vývojářům jazyk vyšší úrovně pro zpracování asynchronních, paralelních úloh a dalších složitých zpracování.

Díky modulu runtime pro správu paměti a objektů jsme se mohli více zaměřit na důležité obchodní aspekty psaní kódu.  Stejně tak má modul runtime, který dokáže spravovat složitost koordinace asynchronní práce, poskytuje sadu funkcí, které zlepšují produktivitu vývojářů.  WF je sada nástrojů pro deklarování pracovního postupu (obchodní logiky), aktivit, které pomáhají definovat logiku a tok řízení a modul runtime pro spuštění výsledné definice aplikace.  WF stručně řečeno používá pro psaní aplikací jazyk vyšší úrovně s cílem zvýšit produktivitu vývojářů, snadnější správu aplikací a rychlejší implementaci.  Modul runtime WF nejen provádí vaše pracovní postupy za vás, ale také poskytuje služby a funkce důležité při psaní aplikační logiky, jako je trvalost stavu, vytváření záložek a obnovení obchodní logiky, z nichž všechny vedou k flexibilitě vláken a procesů, což umožňuje vertikální navýšení a škálování obchodních procesů. 

Další koncepční informace o tom, jak pomocí WF vytvářet aplikace, můžete zvýšit produktivitu, doporučuji přečíst si článek "The Workflow Way" od Davida Chappella, který najdete v části Další zdroje informací. 

Novinky ve WF4

Ve verzi 4 rozhraní Microsoft® .NET Framework zavádí technologie Windows Workflow Foundation významnou změnu oproti předchozím verzím technologie, která byla dodána jako součást rozhraní .NET 3.0 a 3.5.  Ve skutečnosti se tým znovu zaregistroval k jádru programovacího modelu, modulu runtime a nástrojů a každý z nich přepracoval, aby zvýšil výkon a produktivitu a vyřešil důležitou zpětnou vazbu z zapojení zákazníků pomocí předchozích verzí.  Významné změny byly nezbytné k zajištění co nejlepšího prostředí pro vývojáře, kteří přijmou WF, a umožnit, aby WF nadále byla silná základní komponenta, na které můžete ve svých aplikacích stavět. Představím zde změny vysoké úrovně a v celém dokumentu se každý téma bude podrobněji zabývat. 

Než budu pokračovat, je důležité pochopit, že zpětná kompatibilita byla také klíčovým cílem v této verzi.  Nové součásti architektury jsou nalezeny především v sestaveníCh System.Activities.*, zatímco zpětně kompatibilní součásti rozhraní jsou nalezeny v sestaveníCh System.Workflow.* .  Sestavení System.Workflow.* jsou součástí rozhraní .NET Framework 4 a poskytují úplnou zpětnou kompatibilitu, takže můžete migrovat aplikaci na .NET 4 beze změn v kódu pracovního postupu. V tomto dokumentu použijem název WF4 k odkazování na nové součásti nalezené v sestaveníCh System.Activities.* a WF3 odkazovat na součásti nalezené v sestaveníCh System.Workflow.* . 

Návrháři

Jednou z nejviditelnějších oblastí zlepšení je návrhář pracovního postupu. Použitelnost a výkon byly klíčovými cíli týmu pro verzi VS 2010.  Návrhář teď podporuje možnost pracovat s mnohem většími pracovními postupy bez snížení výkonu a návrháři jsou založena na technologii Windows Presentation Foundation (WPF), přičemž plně využívá bohaté uživatelské prostředí, které lze sestavit s deklarativní architekturou uživatelského rozhraní.  Vývojáři aktivit budou používat XAML k definování způsobu, jakým jejich aktivity vypadají a pracují s uživateli v prostředí vizuálního návrhu.  Kromě toho je teď mnohem jednodušší změnit hostitele návrháře pracovních postupů ve vlastních aplikacích, aby ostatní vývojáři mohli zobrazovat pracovní postupy a pracovat s nimi. 

Tok dat

V WF3 byl tok dat v pracovním postupu neprůhlhlý.  WF4 poskytuje jasný a výstižný model pro tok dat a určení rozsahu při použití argumentů a proměnných.  Tyto koncepty, známé všem vývojářům, zjednodušují definici úložiště dat i tok dat do pracovních postupů a aktivit i mimo pracovní postupy a aktivity.  Model toku dat také zviditelňuje očekávané vstupy a výstupy dané aktivity a zlepšuje výkon modulu runtime, protože data jsou snadněji spravovaná. 

Vývojový diagram

Byla přidána nová aktivita toku řízení s názvem Vývojový diagram, která vývojářům umožňuje definovat pracovní postup pomocí modelu vývojového diagramu.  Vývojový diagram blíže připomíná koncepty a myšlenkové procesy, které mnoho analytiků a vývojářů prochází při vytváření řešení nebo navrhování obchodních procesů.  Proto dává smysl poskytovat aktivitu, aby bylo možné snadno modelovat koncepční myšlení a plánování, které už bylo provedeno.  Vývojový diagram umožňuje koncepty, jako je návrat k předchozím krokům a rozdělení logiky na základě jedné podmínky nebo logiky přepínače nebo případu. 

Programovací model

Programovací model WF byl upraven tak, aby byl jednodušší i robustnější.  Aktivita je základní typ v programovacím modelu a představuje pracovní postupy i aktivity.  Kromě toho už nemusíte vytvářet WorkflowRuntime pro vyvolání pracovního postupu, můžete jednoduše vytvořit instanci a spustit ji, zjednodušit testování jednotek a aplikační scénáře, kdy nechcete procházet problémy s nastavením konkrétního prostředí.  Programovací model pracovního postupu se nakonec stane plně deklarativním složením aktivit bez kódu, což zjednodušuje vytváření pracovních postupů.

Integrace wcf (Windows Communication Foundation)

Výhody WF se jistě týkají vytváření služeb i využívání nebo koordinace interakcí služby.  Hodně úsilí se snažilo zlepšit integraci mezi WCF a WF.  Hlavními oblastmi vylepšení jsou nové aktivity zasílání zpráv, korelace zpráv a vylepšená podpora hostování spolu s plně deklarativní definicí služby. 

Začínáme s pracovním postupem

Nejlepším způsobem, jak pochopit WF, je začít ho používat a používat koncepty.  Proberem několik základních konceptů, které se týkají základů pracovního postupu, a pak si projdeme několik jednoduchých pracovních postupů, které ilustrují, jak tyto koncepty vzájemně souvisejí. 

Struktura pracovního postupu

Aktivity jsou stavební bloky WF a všechny aktivity, které jsou nakonec odvozeny od aktivity.  Poznámka k terminologii – Aktivity jsou jednotkou práce ve WF. Aktivity se dají skládat do větších aktivit. Když se aktivita používá jako vstupní bod nejvyšší úrovně, nazývá se "Pracovní postup", stejně jako Main je jednoduše další funkce, která představuje vstupní bod nejvyšší úrovně programů CLR.   Například obrázek 1 ukazuje jednoduchý pracovní postup, který se sestavuje v kódu. 

Sekvence s = nová sekvence

{

    Aktivity = {

        new WriteLine {Text = "Hello"},

        new Sequence {

            Aktivity =

            {

                new WriteLine {Text = "Workflow"},

                new WriteLine {Text = "World"}

            }

        }

    }

};

Obrázek 1: Jednoduchý pracovní postup

Všimněte si, že na obrázku 1 se aktivita sekvence používá jako kořenová aktivita k definování stylu toku kořenového řízení pro pracovní postup. Libovolnou aktivitu lze použít jako kořen nebo pracovní postup a provést, a to i jednoduchý WriteLine.   Nastavením vlastnosti Activities v posloupnosti s kolekcí dalších aktivit jsem definoval strukturu pracovního postupu.  Podřízené aktivity mohou mít také podřízené aktivity a vytvořit strom aktivit, které tvoří celkovou definici pracovního postupu. 

Šablony pracovních postupů a Návrhář pracovního postupu

WF4 se dodává s mnoha aktivitami a sadou Visual Studio 2010 obsahuje šablonu pro definování aktivit. Dvě nejběžnější aktivity používané pro tok kořenového řízení jsou sekvenční a vývojový diagram.  I když je možné jakoukoli aktivitu spustit jako pracovní postup, tyto dvě poskytují nejběžnější vzory návrhu pro definování obchodní logiky.   Obrázek 2 ukazuje příklad sekvenčního modelu pracovního postupu definující zpracování přijaté objednávky, uložení a následné oznámení odesílaná do jiných služeb.   

 

Obrázek 2: Návrh sekvenčního pracovního postupu

Ve WF4 se zavádí typ pracovního postupu vývojového diagramu, který řeší běžné žádosti od stávajících uživatelů, jako je schopnost vrátit se k předchozím krokům pracovního postupu, a protože se více podobá konceptuálnímu návrhu prováděnému analytiky a vývojáři, kteří pracují na definování obchodní logiky.  Představte si například scénář zahrnující uživatelský vstup do vaší aplikace.  V reakci na data poskytnutá uživatelem by váš program měl pokračovat v procesu nebo se vrátit k předchozímu kroku a znovu zobrazit výzvu k zadání vstupu. V sekvenčním pracovním postupu by to zahrnovalo něco podobného, co je znázorněno na obrázku 3, kde se aktivita DoWhile používá k pokračování zpracování, dokud nebude splněna určitá podmínka. 

Obrázek 3: Sekvenční větvení

Návrh na obrázku 3 funguje, ale jako vývojář nebo analytik při pohledu na pracovní postup nepředstavuje původní logiku ani požadavky, které byly popsány.   Pracovní postup vývojového diagramu na obrázku 4 poskytuje podobný technický výsledek sekvenčnímu modelu použitému na obrázku 3, ale návrh pracovního postupu přesněji odpovídá myšlení a požadavkům, jak bylo původně definováno. 

Obrázek 4: Pracovní postup vývojového diagramu

Tok dat v pracovních postupech

První myšlenka, kterou většina lidí má, když si myslí o pracovním postupu, je obchodní proces nebo tok aplikace.  Stejně kritická jako tok jsou data, která řídí proces a informace, které se shromažďují a ukládají během provádění pracovního postupu.  Ve WF4 představuje úložiště a správa dat základní oblast, která je třeba vzít v úvahu. 

Existují tři hlavní koncepty, které je potřeba pochopit s ohledem na data: proměnné, argumenty a výrazy.  Jednoduché definice pro každou z nich jsou, že proměnné slouží k ukládání dat, argumenty jsou pro předávání dat a výrazy slouží k manipulaci s daty. 

Proměnné – ukládání dat

Proměnné v pracovních postupech jsou velmi podobné proměnným, které používáte v imperativních jazycích: popisují pojmenované umístění pro ukládání dat a dodržují určitá pravidla oborů.  Pokud chcete vytvořit proměnnou, nejprve určíte, v jakém oboru musí být proměnná dostupná.  Stejně jako můžete mít proměnné v kódu, které jsou k dispozici na úrovni třídy nebo metody, lze proměnné pracovního postupu definovat v různých oborech.  Zvažte pracovní postup na obrázku 5.  V tomto příkladu můžete definovat proměnnou na kořenové úrovni pracovního postupu nebo v oboru definovaném aktivitou pořadí dat shromažďování informačních kanálů. 

Obrázek 5: Proměnné vymezené na aktivity

Argumenty – předávání dat

Argumenty jsou definovány u aktivit a definují tok dat do a z aktivity.  Argumenty pro aktivity si můžete představit podobně jako argumenty pro metody v imperativním kódu.  Argumenty můžou být In, Out nebo In/Out a mají název a typ.  Při vytváření pracovního postupu můžete definovat argumenty pro kořenovou aktivitu, která umožňuje předání dat do pracovního postupu při jejich vyvolání.  Argumenty pracovního postupu definujete stejně jako proměnné pomocí okna argumentu. 

Při přidávání aktivit do pracovního postupu budete muset nakonfigurovat argumenty pro aktivity a to se provádí především odkazem na proměnné v oboru nebo pomocí výrazů, které proberem dále.  Základní třída argumentu obsahuje vlastnost Expression, která je Aktivita, která vrací hodnotu typu argumentu, takže všechny tyto možnosti jsou související a spoléhají na aktivitu. 

Při úpravě argumentů pomocí návrháře pracovního postupu můžete zadat výrazy představující literální hodnoty do mřížky vlastností nebo použít názvy proměnných k odkazování na proměnnou v oboru, jak je znázorněno na obrázku 6, kde emailResult a emailAddress jsou proměnné definované v pracovním postupu. 

Obrázek 6: Konfigurace argumentů pro aktivity

Výrazy – jednání s daty

Výrazy jsou aktivity, které můžete v pracovním postupu použít k práci s daty.  Výrazy se dají použít na místech, kde používáte aktivitu a zajímá vás návratová hodnota, což znamená, že výrazy můžete použít v nastavení argumentů nebo definovat podmínky pro aktivity, jako jsou aktivity While nebo If.  Mějte na paměti, že většina věcí ve WF4 se odvozuje od aktivity a výrazů se nijak neliší, jedná se o derivát aktivity<TResult> významu, že vrací hodnotu určitého typu.  Kromě toho WF4 obsahuje několik běžných výrazů pro odkazování na proměnné a argumenty a také výrazy jazyka Visual Basic.  Z této vrstvy specializovaných výrazů můžou výrazy, které použijete k definování argumentů, zahrnovat kód, literální hodnoty a odkazy na proměnné.  Tabulka 1 poskytuje malý vzorkování typů výrazů, které můžete použít při definování argumentů pomocí návrháře pracovního postupu.  Při vytváření výrazů v kódu existuje několik dalších možností, včetně použití výrazů lambda. 

Výraz Typ výrazu

"hello world"

Hodnota řetězce literálu

10

Hodnota Literál Int32

System.String.Concat("hello", " ", "world")

Imperativní vyvolání metody

"hello" & "world"

Výraz jazyka Visual Basic

argInputString

Odkaz na argument (název argumentu)

varResult

Odkaz na proměnnou (název proměnné)

"hello: " & argInputString

Literály a argumenty/proměnné jsou smíšené

Tabulka 1: Ukázkové výrazy

Vytvoření prvního pracovního postupu

Teď, když jsem probral základní koncepty související s aktivitou a tokem dat, můžu pomocí těchto konceptů vytvořit pracovní postup.  Začněm jednoduchým pracovním postupem hello world, abych se zaměřil na koncepty a ne na skutečnou hodnotu návrhU WF.  Začněte vytvořením nového projektu testování jednotek v sadě Visual Studio 2010.  Chcete-li použít jádro WF, přidejte odkaz na sestavení System.Activities a přidejte příkazy using pro System.Activities, System.Activities.Statements a System.IO v souboru testovací třídy.  Pak přidejte testovací metodu, jak je znázorněno na obrázku 7, abyste vytvořili základní pracovní postup a spustili ji. 

[TestMethod]

public void TestHelloWorldStatic()

{

    StringWriter writer = new StringWriter();

    Console.SetOut(writer);

    Sequence wf = nová sekvence

    {

        Aktivity = {

            new WriteLine {Text = "Hello"},

            new WriteLine {Text = "World"}

        }

    };

    WorkflowInvoker.Invoke(wf);

    Assert.IsTrue(String.Compare(

        "Hello\r\nWorld\r\n",

        spisovatel. GetStringBuilder(). ToString()) == 0,

        "Nesprávný řetězec napsaný");

}

Obrázek 7: Vytvoření hello world v kódu

Text vlastnost writeLine aktivity je InArgument<řetězec> a v tomto příkladu jsem předal literál hodnotu této vlastnosti.

Dalším krokem je aktualizace tohoto pracovního postupu tak, aby používal proměnné a předávala tyto proměnné argumentům aktivity.  Obrázek 8 ukazuje nový test aktualizovaný tak, aby používal proměnné.

[TestMethod]

public void TestHelloWorldVariables()

{

    StringWriter writer = new StringWriter();

    Console.SetOut(writer);

Sequence wf = nová sekvence

{

    Proměnné = {

        nová proměnná<řetězec>{Default = "Hello", Name = "greeting"},

        new Variable<string> { Default = "Bill", Name = "name" } },

        Aktivity = {

            new WriteLine { Text = new VisualBasicValue<řetězec>("greeting"),

            new WriteLine { Text = new VisualBasicValue<řetězec>(

            "name + \"Gates\"")}

        }

    };

    WorkflowInvoker.Invoke(wf);

}

Obrázek 8: Pracovní postup kódu s proměnnými

V tomto případě jsou proměnné definovány jako typ Proměnná<řetězcové> a mají výchozí hodnotu.  Proměnné jsou deklarovány v rámci aktivity Sequence a následně odkazovány z argumentu Text dvou aktivit.  Alternativně bych mohl použít výrazy k inicializaci proměnných, jak je znázorněno na obrázku 9, kde VisualBasicValue<TResult> třída se používá předávání řetězce představujícího výraz.  V prvním případě výraz odkazuje na název proměnné a v druhém případě je proměnná zřetězena s hodnotou literálu.  Syntaxe použitá v textových výrazech je Visual Basic, i když píšete kód v jazyce C#.

Aktivity = {

    new WriteLine { Text = new VisualBasicValue<řetězec>("greeting"),

        TextWriter = writer },

    new WriteLine { Text = new VisualBasicValue<řetězec>("name + \"Gates\""),

        TextWriter = writer }

}

Obrázek 9: Definování argumentů pomocí výrazů

I když příklady kódu pomáhají ilustrovat důležité body a obecně se cítit pohodlně pro vývojáře, většina lidí použije návrháře k vytváření pracovních postupů.  V návrháři přetáhnete aktivity na návrhovou plochu a použijete aktualizovanou, ale známou mřížku vlastností k nastavení argumentů.  Návrhář pracovního postupu navíc obsahuje rozbalitelné oblasti v dolní části pro úpravu argumentů pro pracovní postup a proměnné.   Pokud chcete v návrháři vytvořit podobný pracovní postup, přidejte do řešení nový projekt, zvolte šablonu Knihovny aktivit a pak přidejte novou aktivitu. 

Při prvním zobrazení návrháře pracovního postupu neobsahuje žádné aktivity.  Prvním krokem při definování aktivity je volba kořenové aktivity.  V tomto příkladu přidejte do návrháře aktivitu vývojového diagramu přetažením z kategorie vývojového diagramu v sadě nástrojů.  V návrháři vývojového diagramu přetáhněte dvě aktivity WriteLine z panelu nástrojů a přidejte je jednu pod druhou do vývojového diagramu.  Teď musíte aktivity propojit, aby vývojový diagram věděl cestu, kterou chcete sledovat.  Uděláte to tak, že nejprve najedete myší na zelený kruh "start" v horní části vývojového diagramu, abyste viděli úchyty pro uchopení, klikněte a přetáhněte ho na první Řádek zápisu a přetáhněte ho na úchyt pro přetažení, který se zobrazí v horní části aktivity.  Totéž proveďte, pokud chcete připojit první WriteLine k druhému WriteLine.  Návrhová plocha by měla vypadat jako obrázek 10. 

Obrázek 10: Rozložení vývojového diagramu Hello

Jakmile je struktura na místě, musíte nakonfigurovat některé proměnné.  Kliknutím na návrhovou plochu a následným kliknutím na tlačítko Proměnné v dolní části návrháře můžete upravit kolekci proměnných vývojového diagramu.  Přidejte do seznamu dvě proměnné s názvem "greeting" a "name" a nastavte výchozí hodnoty na "Hello" a "Bill". Při nastavování hodnot nezapomeňte zahrnout uvozovky, protože se jedná o výraz, takže literální řetězce musí být citované.  Obrázek 11 znázorňuje okno proměnných nakonfigurované se dvěma proměnnými a jejich výchozími hodnotami. 

Obrázek 11: Proměnné definované v návrháři pracovních postupů

Pokud chcete tyto proměnné použít v aktivitách WriteLine, zadejte "greeting" (bez uvozovek) do mřížky vlastností pro argument Text první aktivity a "name" (opět bez uvozovek) pro argument Text na druhém WriteLine.   Při vyhodnocování argumentů Text v době běhu se hodnota v proměnné přeloží a použije aktivita WriteLine.

V testovacím projektu přidejte odkaz na projekt obsahující váš pracovní postup.  Pak můžete přidat testovací metodu, jak je znázorněno na obrázku 12, a vyvolat tento pracovní postup a otestovat výstup.  Na obrázku 12 vidíte, že se pracovní postup vytváří vytvořením instance vytvořené třídy.  V tomto případě byl pracovní postup definován v návrháři a zkompilován do třídy odvozené z aktivity, která se pak může vyvolat. 

[TestMethod]

public void TestHelloFlowChart()

{

    StringWriter tWriter = new StringWriter();

    Console.SetOut(tWriter);

    Workflows.HelloFlow wf = new Workflows.HelloFlow();

    WorkflowInvoker.Invoke(wf);

    Výrazy se vynechaly.

}

obrázek 12: Testování vývojového diagramu

Zatím jsem v pracovním postupu používal proměnné a jejich použití k zadání hodnot argumentům v aktivitách WriteLine.  Pracovní postup může mít také definované argumenty, které umožňují předat data do pracovního postupu při jeho vyvolání a příjem výstupu po dokončení pracovního postupu.  Pokud chcete vývojový diagram aktualizovat z předchozího příkladu, odeberte proměnnou name (vyberte ji a stiskněte klávesu Delete) a místo toho vytvořte argument "name" typu řetězec.  Uděláte to úplně stejným způsobem, s výjimkou použití tlačítka Argumenty k zobrazení editoru argumentů.  Všimněte si, že argumenty mohou mít také směr a nemusíte zadávat výchozí hodnotu, protože hodnota bude předána do aktivity za běhu.  Vzhledem k tomu, že pro proměnnou používáte stejný název jako u proměnné, zůstávají argumenty textových argumentů aktivity WriteLine platné.  Nyní za běhu tyto argumenty vyhodnotí a přeloží hodnotu argumentu "name" v pracovním postupu a použije tuto hodnotu.  Přidejte další argument typu řetězec se směrem Ven a názvem "fullGreeting"; vrátí se do volajícího kódu. 

obrázek 13: Definování argumentů pro pracovního postupu

V vývojovém diagramu přidejte aktivitu Assign a připojte ji k poslední aktivitě WriteLine.  Do argumentu Komu zadejte "fullGreeting" (bez uvozovek) a jako argument Hodnota zadejte "greeting & name" (bez uvozovek). Tím se přiřadí zřetězení proměnné pozdravu s argumentem name k výstupnímu argumentu fullGreeting. 

Nyní v testu jednotek aktualizujte kód tak, aby při vyvolání pracovního postupu argument dodal.  Argumenty jsou předány pracovnímu postupu jako slovníkový<řetězec, objekt>, kde klíč je název argumentu.  Můžete to udělat jednoduše tak, že změníte volání vyvolání pracovního postupu, jak je znázorněno na obrázku 14. Všimněte si, že výstupní argumenty jsou také obsaženy v řetězci<slovníku, objekt> kolekci klíčí na název argumentu. 

IDictionary<string, object> results = WorkflowInvoker.Invoke(wf;

    new Dictionary<string,object> {

        {"name", "Bill" } }

    );

string outValue = results["fullGreeting"]. ToString();

obrázek 14: Předání argumentů pracovnímu

Teď, když jste viděli základy, jak seskupit aktivity, proměnné a argumenty, vás provedem prohlídkou aktivit zahrnutých v rámci architektury, aby bylo možné zajímavější pracovní postupy zaměřené na obchodní logiku místo konceptů nízké úrovně.

Prohlídka palety aktivit pracovního postupu

U libovolného programovacího jazyka očekáváte, že budete mít základní konstrukce pro definování logiky aplikace.  Pokud používáte vývojovou architekturu vyšší úrovně, jako je WF, očekávání se nezmění.   Stejně jako příkazy v jazycích .NET, jako jsou If/Else, Switch a While, ke správě toku řízení potřebujete stejné funkce i při definování logiky v deklarativním pracovním postupu.  Tyto funkce mají formu základní knihovny aktivit, která se dodává s architekturou.  V této části vám poskytnem rychlou prohlídku aktivit, které jsou dodávány s architekturou, abyste získali představu o funkcích poskytovaných předem.

Primitiva aktivit a aktivity kolekce

Při přechodu na deklarativní programovací model je snadné začít přemýšlet o tom, jak provádět běžné úlohy manipulace s objekty, které jsou druhou povahou při psaní kódu.  Pro úlohy, ve kterých zjistíte, že pracujete s objekty a potřebujete nastavit vlastnosti, vyvolat příkazy nebo spravovat kolekci položek, existuje sada aktivit navržených speciálně s těmito úkoly. 

Aktivita Popis

Přiřadit

Přiřadí hodnotu k umístění – povolí nastavení proměnných.

Zpoždění

Zpožďuje cestu provádění po zadanou dobu.

InvokeMethod

Vyvolá metodu pro objekt .NET nebo statickou metodu typu .NET, volitelně s návratovým typem T.

WriteLine

Zapisuje zadaný text do zapisovače textu – výchozí hodnota je Console.Out.

AddToCollection<T>

Přidá položku do zadané kolekce.

RemoveFromCollection<T>

Odebere položku z typované kolekce.

ClearCollection<T>

Odebere všechny položky z kolekce.

ExistsInCollection<T>

Vrátí logickou hodnotu označující, jestli zadaná položka existuje v kolekci. 

 

Aktivity toku řízení

Při definování obchodní logiky nebo obchodních procesů je důležité mít kontrolu nad tokem provádění. Aktivity toku řízení zahrnují základy, jako je sequence, která poskytuje společný kontejner, když potřebujete provést kroky v uvedeném pořadí, a běžnou logiku větvení, jako jsou aktivity If a Switch.  Aktivity toku řízení zahrnují také logiku smyčky založenou na datech (ForEach) a Podmínkách (While).  Nejdůležitější pro zjednodušení komplexního programování jsou paralelní aktivity, které umožňují současně provádět více asynchronních aktivit. 

Aktivita Popis

Posloupnost

Pro provádění aktivit v řadě

While/Do DoWhile

Spustí podřízenou aktivitu, když je podmínka (výraz) pravdivá.

> ForEach<T

Iteruje nad výčtovou kolekcí a spustí podřízenou aktivitu jednou pro každou položku v kolekci a čeká na dokončení podřízené položky před zahájením další iterace. Poskytuje typový přístup k jednotlivé položce, která řídí iteraci ve formě pojmenovaného argumentu.

Když

Provede jednu ze dvou podřízených aktivit v závislosti na výsledku podmínky (výraz).

Přepnutí<T>

Vyhodnotí výraz a naplánuje podřízenou aktivitu pomocí odpovídajícího klíče. 

Rovnoběžný

Naplánuje všechny podřízené aktivity najednou, ale také poskytuje podmínku dokončení, která aktivitě umožní zrušit všechny nevyřízených podřízených aktivit, pokud jsou splněny určité podmínky. 

ParallelForEach<T>

Iteruje nad výčtovou kolekcí a spustí podřízenou aktivitu jednou pro každou položku v kolekci, přičemž všechny instance se plánují současně. Podobně jako forEach<T>tato aktivita poskytuje přístup k aktuální datové položce ve formě pojmenovaného argumentu.

Krumpáč

Naplánuje všechny podřízené aktivity PickBranch a zruší všechny, ale první, aby byla aktivační událost dokončena.  Aktivita PickBranch má aktivační událost i akci; každá je aktivita.  Po dokončení aktivity triggeru zruší výběr všechny ostatní podřízené aktivity. 

 Následující dva příklady ukazují několik z těchto aktivit, které se používají k znázornění toho, jak tyto aktivity seskupit dohromady.  První příklad, obrázek 15, obsahuje použití ParallelForEach<T> k použití seznamu adres URL a asynchronně získat informační kanál RSS na zadanou adresu.  Po vrácení informačního kanálu se forEach<T> použije k iteraci položek informačního kanálu a jejich zpracování. 

Všimněte si, že kód deklaruje a definuje instanci VisualBasicSettings s odkazy na typy System.ServiceModel.Syndication.  Tento objekt nastavení se pak použije při deklarování visualBasicValue<T> instancí odkazujících na typy proměnných z tohoto oboru názvů k povolení překladu typů pro tyto výrazy.  Všimněte si také, že tělo aktivity ParallelForEach přijímá ActivityAction, které jsou uvedeny v části vytváření vlastních aktivit.  Tyto akce používají DelegateInArgument a DelegateOutArgument stejným způsobem jako aktivity používají InArgument a OutArgument. 

Obrázek 15: Aktivity toku řízení

Druhý příklad, obrázek 16, je běžný způsob čekání na odpověď s časovým limitem.  Například čekání na schválení žádosti nadřízeným a odeslání připomenutí, pokud odpověď nedorazila v přiděleném čase.  Aktivita DoWhile způsobí opakování čekání na odpověď, zatímco aktivita Pick se používá ke spuštění aktivity ManagerResponse i aktivity delay ve stejnou dobu jako triggery.  Po dokončení zpoždění se nejprve odešle připomenutí a po dokončení aktivity ManagerResponse se příznak nastaví tak, aby se přerušil smyčky DoWhile. 

obrázek 16: Aktivity Výběr a DoWhile

Příklad na obrázku 16 také ukazuje, jak lze záložky použít v pracovních postupech.  Záložku vytvoří aktivita, která označí místo v pracovním postupu, aby zpracování bylo možné v tomto okamžiku obnovit později.  Aktivita Delay má záložku, která se obnoví po uplynutí určité doby.  Aktivita ManagerResponse je vlastní aktivita, která čeká na vstup a obnoví pracovní postup po doručení dat.  Aktivity zasílání zpráv, probírané za chvíli, jsou hlavními aktivitami pro provádění záložek.  Pokud pracovní postup aktivně zpracovává práci, když čeká jenom na obnovení záložek, považuje se za nečinný a může být trvalý v trvalém úložišti.  Záložky budou podrobněji popsány v části o vytváření vlastních aktivit. 

Migrace

Pro vývojáře, kteří používají WF3, může aktivita spolupráce hrát zásadní roli při opakovaném použití stávajících prostředků. Aktivita, která se nachází v sestavení System.Workflow.Runtime, zabalí váš existující typ aktivity a zobrazí vlastnosti aktivity jako argumenty v modelu WF4.  Vzhledem k tomu, že vlastnosti jsou argumenty, můžete k definování hodnot použít výrazy.  Obrázek 17 znázorňuje konfiguraci aktivity spolupráce pro volání aktivity WF3.  Vstupní argumenty jsou definovány odkazy na proměnné v oboru v rámci definice pracovního postupu.    Aktivity integrované ve WF3 měly vlastnosti místo argumentů, takže každá vlastnost má odpovídající vstupní a výstupní argument, který umožňuje odlišit data odesílaná do aktivity a data, která očekáváte, že se po provedení aktivity načtou. V novém projektu WF4 tuto aktivitu nenajdete v sadě nástrojů, protože cílová architektura je nastavena na .NET Framework 4 Client Profile.  Změňte cílovou architekturu ve vlastnostech projektu na .NET Framework 4 a aktivita se zobrazí v sadě nástrojů.

Obrázek 17: Konfigurace aktivity spolupráce

Vývojový diagram

Při navrhování pracovních postupů vývojového diagramu existuje několik konstruktorů, které lze použít ke správě toku provádění v rámci vývojového diagramu.  Tyto konstrukce samy poskytují jednoduché kroky, jednoduché rozhodovací body založené na jedné podmínce nebo příkazu switch.  Skutečnou silou vývojového diagramu je schopnost připojit tyto typy uzlů k požadovanému toku.

Konstrukce/aktivita Popis

Vývojový diagram

Kontejner pro řadu kroků toku může být každá aktivita nebo jeden z následujících konstruktorů, ale ke spuštění musí být připojen v rámci vývojového diagramu. 

FlowDecision

Poskytuje logiku větvení na základě podmínky.

FlowSwitch<T>

Umožňuje více větví na základě hodnoty výrazu. 

FlowStep

Představuje krok v vývojovém diagramu s možností připojení k dalším krokům. Tento typ se nezobrazuje v sadě nástrojů, protože je implicitně přidán návrhářem.  Tato aktivita zabalí další aktivity v pracovním postupu a poskytuje sémantiku navigace pro další kroky v pracovním postupu. 

Je důležité si uvědomit, že i když existují konkrétní aktivity pro model vývojového diagramu, lze v rámci pracovního postupu použít všechny další aktivity.  Podobně lze do jiné aktivity přidat aktivitu vývojového diagramu, která poskytuje sémantiku provádění a návrhu vývojového diagramu v rámci tohoto pracovního postupu.  To znamená, že můžete mít posloupnost s několika aktivitami a vývojovým diagramem přímo uprostřed. 

Aktivity zasílání zpráv

Jedním z hlavních zaměření ve WF4 je užší integrace mezi WF a WCF.  Z hlediska pracovních postupů to znamená aktivity pro modelování operací zasílání zpráv, jako je odesílání a příjem zpráv.  V rámci architektury pro zasílání zpráv je ve skutečnosti zahrnuto několik různých aktivit, z nichž každá má mírně odlišné funkce a účel. 

Aktivita Popis

Odesílání a přijímání

Jedním ze způsobů, jak posílat nebo přijímat zprávy aktivity zasílání zpráv.  Tyto stejné aktivity se skládají do interakcí stylu požadavků a odpovědí. 

ReceiveAndSendReply

Modeluje operaci služby, která přijímá zprávu a odesílá odpověď zpět. 

SendAndReceiveReply

Vyvolá operaci služby a obdrží odpověď. 

InitializeCorrelation

Umožňuje explicitně inicializovat hodnoty korelace jako součást logiky pracovního postupu místo extrahování hodnot ze zprávy. 

CorrelationScope

Definuje rozsah provádění, kde je popisovač korelace přístupný pro příjem a odesílání aktivit, což zjednodušuje konfiguraci popisovače, který je sdílen několika aktivitami zasílání zpráv. 

TransactedReceiveScope

Umožňuje zahrnout logiku pracovního postupu do stejné transakce toku do operace WCF pomocí aktivity Receive.

Pokud chcete vyvolat operaci služby z pracovního postupu, postupujte podle známých kroků přidání odkazu na službu do projektu pracovního postupu.  Systém projektu v sadě Visual Studio pak bude využívat metadata ze služby a vytvořit vlastní aktivitu pro každou operaci služby nalezenou ve smlouvě.  Můžete si to představit jako ekvivalent pracovního postupu proxy serveru WCF, který by byl vytvořen v projektu jazyka C# nebo Visual Basic.   Například když vezmete existující službu, která hledá rezervace hotelů pomocí smlouvy o poskytování služeb znázorněnou na obrázku 18; přidání odkazu na službu přináší vlastní aktivitu zobrazenou na obrázku 19. 

[ServiceContract]

veřejné rozhraní IHotelService

{

    [OperationContract]

    Seznam<HotelSearchResult> SearchHotels(

        HotelSearchRequest requestDetails);

}

obrázek 18: Servisní kontrakt

Obrázek 19: Vlastní aktivit WCF

Další informace o vytváření pracovních postupů vystavených jako služby WCF najdete v části Služby pracovního postupu dále v tomto dokumentu. 

Transakce a zpracování chyb

Psaní spolehlivých systémů může být obtížné a vyžaduje, abyste udělali dobrou práci při zpracování chyb a správě, aby se zachoval konzistentní stav ve vaší aplikaci.  U pracovního postupu se obory pro správu zpracování výjimek a transakcí modelují pomocí aktivit s vlastnostmi typu ActivityAction nebo Activity, aby vývojáři mohli modelovat logiku zpracování chyb.  Kromě těchto běžných vzorů konzistence obsahuje WF4 také aktivity, které umožňují modelovat dlouho běžící distribuovanou koordinaci prostřednictvím kompenzace a potvrzení. 

Aktivita Popis

CancellationScope

Slouží k tomu, aby vývojář pracovního postupu reagoval, pokud dojde ke zrušení textu práce. 

TransactionScope

Umožňuje sémantiku podobnou použití oboru transakce v kódu spuštěním všech podřízených aktivit v oboru v rámci transakce. 

TryCatch/Catch<T>

Používá se k modelování zpracování výjimek a zachytávání typových výjimek. 

Hodit

Lze použít k vyvolání výjimky z aktivity.  

Zvětšovat

Používá se k opětovnému zvětšování výjimky, obecně jedna, která byla zachycena pomocí aktivity TryCatch. 

CompensableActivity

Definuje logiku pro provádění podřízených aktivit, které můžou po úspěchu kompenzovat jejich akce.  Poskytuje zástupný symbol pro logiku kompenzace, logiku potvrzení a zpracování zrušení.

Odškodnit

Vyvolá logiku zpracování kompenzace pro kompenzovatelnou aktivitu.

Potvrdit

Vyvolá logiku potvrzení pro kompenzovatelnou aktivitu. 

Aktivita TryCatch poskytuje známý způsob, jak nastavit obor sady práce k zachycení všech výjimek, ke kterým může dojít, a aktivita Catch<T> poskytuje kontejner pro logiku zpracování výjimek.  Příklad použití této aktivity na obrázku 20, přičemž každý typový blok výjimky definovaný aktivitou Catch<T> poskytuje přístup k výjimce prostřednictvím pojmenovaného argumentu zobrazeného na levé straně každého catchu.   Pokud nastane potřeba, můžete aktivitu Rethrow použít k opětovnému zvětšování zachycené výjimky nebo k vyvolání nové výjimky z vaší vlastní. 

Obrázek 20: Aktivita TryCatch

Transakce pomáhají zajistit konzistenci v krátkodobé práci a aktivita TransactionScope poskytuje stejný druh rozsahu, který můžete získat v kódu .NET pomocí TransactionScope třídy. 

A konečně, pokud potřebujete zachovat konzistenci, ale nemůžete použít atomické transakce napříč prostředky, můžete použít kompenzaci.  Kompenzace umožňuje definovat sadu práce, která může mít v případě dokončení sadu aktivit, které mohou kompenzovat provedené změny.  Jako jednoduchý příklad zvažte aktivitu compensable na obrázku 21, kde se posílá e-mail.  Pokud po dokončení aktivity dojde k výjimce, může být vyvolána logika kompenzace, která systém vrátí zpět do konzistentního stavu; v tomto případě se zobrazí e-mail s následným odvoláním předchozí zprávy. 

obrázek 21: s možností vytváření

Vytváření a spouštění pracovních postupů

Stejně jako u každého programovacího jazyka existují dvě základní věci, které s pracovními postupy děláte: definovat je a spouštět je.  V obou případech poskytuje WF několik možností, které vám poskytnou flexibilitu a kontrolu. 

Možnosti návrhu pracovních postupů

Při navrhování nebo definování pracovních postupů existují dvě hlavní možnosti: kód nebo XAML. XAML poskytuje skutečně deklarativní prostředí a umožňuje definovat celou definici pracovního postupu v kódu XML a odkazovat na aktivity a typy vytvořené pomocí .NET.  Většina vývojářů pravděpodobně použije návrháře pracovního postupu k sestavení pracovních postupů, což bude mít za následek deklarativní definici pracovního postupu XAML.  Vzhledem k tomu, že XAML je pouze XML, můžete ho ale použít k jeho vytvoření, což je jedním z důvodů, proč je to takový výkonný model pro vytváření aplikací.  Například XAML zobrazený na obrázku 22 byl vytvořen v jednoduchém textovém editoru a lze jej zkompilovat nebo použít přímo ke spuštění instance definovaného pracovního postupu. 

<p:Activity x:Class="Workflows.HelloSeq" xmlns="https://schemas.microsoft.com/netfx/2009/xaml/activities/design" xmlns:p="https://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">

  <x:Members>

    <x:Property Name="greeting" Type="p:InArgument(x:String)" />

    <x:Property Name="name" Type="p:InArgument(x:String)" />

  </x:Members>

  <p:Sequence>

    <p:WriteLine>[pozdrav & " from workflow"]</p:WriteLine>

    <p:WriteLine>[name]</p:WriteLine>

  </p:Sequence>

</p:Activity>

Obrázek 22: Pracovní postup definovaný v XAML

Stejný xaml je generován návrhářem a může být generován vlastními nástroji, což usnadňuje správu.  Kromě toho je také možné, jak bylo znázorněno dříve, k vytváření pracovních postupů pomocí kódu.  To zahrnuje vytvoření hierarchie aktivit prostřednictvím použití různých aktivit v rámci a vlastních aktivit.  Už jste viděli několik příkladů pracovních postupů definovaných zcela v kódu.  Na rozdíl od WF3 je nyní možné vytvořit pracovní postup v kódu a snadno ho serializovat do XAML; poskytuje větší flexibilitu při modelování a správě definic pracovních postupů. 

Jak si ukážem, ke spuštění pracovního postupu je vše, co potřebujete, aktivita a to může být instance integrovaná v kódu nebo jedna vytvořená z XAML.  Konečným výsledkem každé techniky modelování je třída odvozená z aktivity nebo reprezentace XML, která může být deserializována nebo zkompilována do aktivity. 

Možnosti spouštění pracovních postupů

Ke spuštění pracovního postupu potřebujete aktivitu, která definuje pracovní postup.  Existují dva typické způsoby, jak získat aktivitu, kterou lze provést: vytvořit ji v kódu nebo číst v souboru XAML a deserializovat obsah do aktivity.  První možnost je jednoduchá a už jsem ukázal několik příkladů.  K načtení souboru XAML byste měli použít ActivityXamlServices třídy, která poskytuje statickou metodu Load.  Jednoduše předejte objekt Stream nebo XamlReader a získáte zpět aktivitu reprezentovanou v XAML.  

Jakmile máte aktivitu, nejjednodušší způsob, jak ji spustit, je pomocí WorkflowInvoker třídy, jak jsem to udělal v testech jednotek dříve.  Metoda Invoke této třídy má parametr typu Activity a vrátí IDictionary<řetězec, objekt>.  Pokud potřebujete předat argumenty do pracovního postupu, nejprve je definujete v pracovním postupu a pak předáte hodnoty spolu s aktivitou do metody Invoke jako slovník párů název/hodnota.  Stejně tak se vrátí všechny argumenty Out nebo In/Out definované v pracovním postupu jako výsledek provedení metody.  Obrázek 23 představuje příklad načtení pracovního postupu ze souboru XAML, předání argumentů do pracovního postupu a načtení výsledných výstupních argumentů. 

MathWF aktivity;

using (Stream mathXaml = File.OpenRead("Math.xaml"))

{

    mathWF = ActivityXamlServices.Load(mathXaml);

}

var outputs = WorkflowInvoker.Invoke(mathWF;

    new Dictionary<string, object> {

    { "operand1", 5 },

    { "operand2", 10 },

    { "operation", "add" } });

Assert.AreEqual<int>(15, (int)outputs["result"], "Nesprávný výsledek vrácen");

obrázek 23: Vyvolání pracovního postupu "Volné XAML" s argumenty in a out

Všimněte si v tomto příkladu, že aktivita je načtena ze souboru XAML a stále může přijímat a vracet argumenty.  Pracovní postup byl vyvinut pomocí návrháře v sadě Visual Studio, ale mohl by být vyvinut ve vlastním návrháři a uložen kdekoli.  Xaml může být načten z databáze, knihovny SharePointu nebo jiného úložiště před předáním modulu runtime ke spuštění.  

Použití WorkflowInvoker poskytuje nejjednodušší mechanismus pro spouštění krátkodobých pracovních postupů.  Pracovní postup v podstatě funguje jako volání metody ve vaší aplikaci, což vám umožní snadněji využít všechny výhody WF, aniž byste museli provádět spoustu práce na hostování samotného WF.  To je užitečné zejména při testování částí vašich aktivit a pracovních postupů, protože snižuje nastavení testu potřebné k cvičení komponenty v rámci testu. 

Další běžnou třídou hostování je WorkflowApplication, která poskytuje bezpečný popisovač pracovního postupu, který se spouští v modulu runtime, a umožňuje snadněji spravovat dlouhotrvající pracovní postupy.  Pomocí WorkflowApplication můžete stále předávat argumenty do pracovního postupu stejným způsobem jako u WorkflowInvoker, ale pomocí metody Run skutečně spustit pracovní postup.  V tomto okamžiku se pracovní postup začne spouštějí v jiném vlákně a ovládací prvek se vrátí do volajícího kódu. 

Vzhledem k tomu, že pracovní postup je nyní spuštěn asynchronně, budete v hostitelském kódu pravděpodobně chtít vědět, kdy se pracovní postup dokončí, nebo pokud vyvolá výjimku atd. U těchto typů oznámení má třída WorkflowApplication sadu vlastností typu Action<T>, které lze použít jako události k přidání kódu pro reakci na určité podmínky provádění pracovního postupu, včetně: přerušeno, neošetřené výjimky, dokončeno, idled a uvolněno.  Při provádění pracovního postupu pomocí WorkflowApplication můžete použít kód podobný jako na obrázku 24 pomocí akcí pro zpracování událostí. 

WorkflowApplication wf = new WorkflowApplication(new Flowchart1());

Wf. Completed = delegate(WorkflowApplicationCompletedEventArgs e)

{

    Console.WriteLine("Pracovní postup {0} dokončen", e.InstanceId);

};

Wf. Aborted = delegate(WorkflowApplicationAbortedEventArgs e)

{

    Console.WriteLine(e.Reason);

};

Wf. OnUnhandledException =

  delegate(WorkflowApplicationUnhandledExceptionEventArgs e)

  {

      Console.WriteLine(e.UnhandledException.ToString());

      return UnhandledExceptionAction.Terminate;

  };

Wf. Run();

Obrázek 24: Akce aplikace pracovního postupu

V tomto příkladu je cílem kódu hostitele, jednoduché konzolové aplikace, upozornit uživatele prostřednictvím konzoly, jakmile se pracovní postup dokončí nebo dojde k chybě.  V reálném systému se hostitel bude zajímat o tyto události a bude na ně pravděpodobně reagovat jinak, aby správcům poskytl informace o selháních nebo lépe spravoval instance.

Rozšíření pracovního postupu

Jednou ze základních funkcí WF od WF3 bylo, že je dostatečně odlehčené, aby bylo možné hostovat v jakékoli doméně aplikace .NET.  Vzhledem k tomu, že modul runtime se může spouštět v různých doménách a může potřebovat přizpůsobenou sémantiku spouštění, je potřeba z modulu runtime externalizovat různé aspekty chování modulu runtime.  To je místo, kde rozšíření pracovních postupů přicházejí do hry.  Rozšíření pracovního postupu umožňují jako vývojář psát kód hostitele, pokud se tak rozhodnete, přidat chování do modulu runtime rozšířením s vlastním kódem. 

Dva typy rozšíření, o které modul runtime WF vědí, jsou trvalost a sledování rozšíření. Rozšíření trvalosti poskytuje základní funkce pro uložení stavu pracovního postupu do trvalého úložiště a načtení tohoto stavu v případě potřeby.  Odesílání rozšíření trvalosti s architekturou zahrnuje podporu microsoft SQL Serveru, ale rozšíření lze zapsat pro podporu jiných databázových systémů nebo trvalých úložišť. 

Perzistence

Chcete-li použít rozšíření trvalosti, musíte nejprve nastavit databázi pro uložení stavu, který lze provést pomocí skriptů SQL nalezených v %windir%\Microsoft.NET\Framework\v4.0.30319\sql\<jazyk> (např. c:\windows\microsoft.net\framework\v4.0.30319\sql\en\). Po vytvoření databáze spustíte dva skripty, které vytvoří strukturu (SqlWorkflowInstanceStoreSchema.sql) i uložené procedury (SqlWorkflowInstanceStoreLogic.sql) v databázi. 

Jakmile je databáze nastavena, použijete SqlWorkflowInstanceStore spolu s WorkflowApplication třídy.  Nejprve vytvoříte úložiště a nakonfigurujete ho a pak ho zadáte do aplikace WorkflowApplication, jak je znázorněno na obrázku 25.

Aplikace WorkflowApplication = nová aplikace WorkflowApplication(aktivita);

InstanceStore instanceStore = new SqlWorkflowInstanceStore(

    @"Data Source=.\\SQLEXPRESS;Integrated Security=True");

Zobrazení InstanceView = instanceStore.Execute(

    instanceStore.CreateInstanceHandle(), nový CreateWorkflowOwnerCommand(),

    TimeSpan.FromSeconds(30));

instanceStore.DefaultInstanceOwner = view. Vlastník instance;

aplikace. InstanceStore = instanceStore;

obrázek 25: Přidání zprostředkovatele trvalosti SQL

Pracovní postup se dá zachovat dvěma způsoby.  Prvním je přímé použití aktivity Trvalá v pracovním postupu.  Když tato aktivita provede, způsobí, že se stav pracovního postupu zachová do databáze a uloží aktuální stav pracovního postupu.  To umožňuje autorovi pracovního postupu řídit, kdy je důležité uložit aktuální stav pracovního postupu.  Druhá možnost umožňuje hostitelské aplikaci zachovat stav pracovního postupu, když v instanci pracovního postupu dojde k různým událostem; s největší pravděpodobností je pracovní postup nečinný.  Registrací akce PersistableIdle pro WorkflowApplication pak váš kód hostitele může reagovat na událost, která označuje, jestli má být instance trvalá, uvolněná nebo ani jedna.  Obrázek 26 ukazuje hostitelskou aplikaci, která se registruje, aby dostávala oznámení, když je pracovní postup nečinný a způsobuje jeho trvalé uložení. 

Wf. PersistableIdle = (waie) => PersistableIdleAction.Persist;

obrázek 26: Uvolnění pracovního postupu při

Jakmile je pracovní postup zpracovaný a trvalý, může ho modul runtime WF uvolnit z paměti a uvolnit prostředky pro jiné pracovní postupy, které potřebují zpracování.  Instanci pracovního postupu můžete uvolnit vrácením příslušného výčtu z akce PersistableIdle.  Jakmile se pracovní postup uvolní, v určitém okamžiku ho hostitel bude chtít znovu načíst z úložiště trvalosti a obnovit ho.  Aby to bylo možné provést, musí být instance pracovního postupu načtena pomocí úložiště instancí a identifikátoru instance. To zase způsobí, že úložiště instancí bude vyzváno k načtení stavu.  Po načtení stavu je možné použít metodu Run na WorkflowApplication nebo záložku obnovit, jak je znázorněno na obrázku 27.  Další informace o záložkách najdete v části vlastní aktivity. 

Aplikace WorkflowApplication = nová aplikace WorkflowApplication(aktivita);

aplikace. InstanceStore = instanceStore;

aplikace. Load(ID);

aplikace. ResumeBookmark(readLineBookmark; input);

Obrázek 27: Obnovení trvalého pracovního postupu

Jednou z změn ve WF4 je způsob, jakým se stav pracovních postupů zachovává a spoléhá na nové techniky správy dat argumentů a proměnných.  Místo serializace celého stromu aktivit a udržování stavu po dobu životnosti pracovního postupu jsou zachovány pouze v proměnných oboru a hodnot argumentů spolu s některými daty modulu runtime, jako jsou například informace o záložkách.  Všimněte si na obrázku 27, že při opětovném načtení trvalé instance se kromě použití úložiště instancí předává také aktivita, která definuje pracovní postup. V podstatě se stav z databáze použije na zadanou aktivitu.  Tato technika umožňuje mnohem větší flexibilitu pro správu verzí a vede k lepšímu výkonu, protože stav má menší nároky na paměť. 

Sledování

Trvalost umožňuje hostiteli podporovat dlouhotrvající procesy, vyrovnávat zatížení instancí mezi hostiteli a další chování odolné proti chybám.  Po dokončení instance pracovního postupu se ale stav v databázi často odstraní, protože už není užitečný.  V produkčním prostředí je důležité mít informace o tom, co pracovní postup v současné době dělá a co udělal, pro správu pracovních postupů i získání přehledu o obchodním procesu.  Schopnost sledovat, co se děje ve vaší aplikaci, je jednou z poutavých funkcí používání modulu runtime WF.  

Sledování se skládá ze dvou primárních součástí: sledování účastníků a profilů sledování.  Profil sledování definuje, jaké události a data má modul runtime sledovat. Profily můžou obsahovat tři primární typy dotazů:

  • ActivityStateQuery – slouží k identifikaci stavů aktivit (např. uzavřených) a proměnných nebo argumentů pro extrakci dat.
  • WorkflowInstanceQuery – slouží k identifikaci událostí pracovního postupu.
  • CustomTrackingQuery – slouží k identifikaci explicitních volání ke sledování dat, obvykle v rámci vlastních aktivit.

Například obrázek 28 ukazuje vytvoření trackingProfile, který zahrnuje ActivityStateQuery a WorkflowInstanceQuery.   Všimněte si, že dotazy indikují, kdy shromažďovat informace, a také jaká data se mají shromažďovat.  Pro ActivityStateQuery jsem zahrnul seznam proměnných, které by měly mít jejich hodnotu extrahované a přidané do sledovaných dat. 

Profil TrackingProfile = nový TrackingProfile

{

    Name = "SimpleProfile",

    Dotazy = {

        new WorkflowInstanceQuery {

            States = { "*" }

        },

        new ActivityStateQuery {

            ActivityName = "WriteLine",

            States={ "*" },

            Proměnné = {"Text" }

        }

    }

};

Obrázek 28: Vytvoření profilu sledování

Účastník sledování je rozšíření, které lze přidat do modulu runtime a zodpovídá za zpracování sledovacích záznamů při jejich vygenerování.  Základní třída TrackingParticipant definuje vlastnost pro poskytnutí TrackingProfile a Track metody, která zpracovává sledování.  Obrázek 29 ukazuje omezený vlastní účastník sledování, který zapisuje data do konzoly.  Aby bylo možné použít účastníka sledování, musí být inicializován s profilem sledování a poté přidán do kolekce rozšíření v instanci pracovního postupu. 

veřejná třída ConsoleTrackingParticipant : TrackingParticipant

{

   protected override void Track(TrackingRecord record, TimeSpan timeout)

   {

      ActivityStateRecord aRecord = record as ActivityStateRecord;

      if (aRecord != null)

      {

         Console.WriteLine("{0} zadaný stav {1}",

            aRecord.Activity.Name, aRecord.State);

         foreach (var item in aRecord.Arguments)

         {

            Console.ForegroundColor = ConsoleColor.Cyan;

            Console.WriteLine("Variable:{0} má hodnotu: {1}",

                položka. Klíč, položka. Hodnota);

            Console.ResetColor();

         }

      }

   }

}

Obrázek 29: Účastník sledování konzoly

WF se dodává s EtwTrackingParticipant (ETW = Enterprise Trace pro Windows), které můžete přidat do modulu runtime, abyste umožnili sledování dat s vysokým výkonem.  EtW je trasovací systém, který je nativní komponentou ve Windows a používá mnoho komponent a služeb v operačním systému, včetně ovladačů a dalšího kódu na úrovni jádra.  Data zapsaná do windows Windows Server AppFabric je možné využívat pomocí vlastního kódu nebo pomocí nástrojů, jako je nadcházející Windows Server AppFabric.  Pro uživatele, kteří migrují z WF3, se to změní, protože v rámci architektury nebude doručovat účastník sledování SQL.  Windows Server AppFabric se ale bude dodávat se spotřebiteli windows Serveru AppFabric, kteří shromáždí data ETW a uloží je do databáze SQL.  Podobně můžete vytvořit příjemce Trasování událostí pro Windows a uložit data v libovolném formátu, nebo napsat vlastního účastníka sledování, podle toho, co dává smysl pro vaše prostředí. 

Vytváření vlastních aktivit

I když základní knihovna aktivit obsahuje bohatou paletu aktivit pro interakci se službami, objekty a kolekcemi, neposkytuje aktivity pro interakci s subsystémy, jako jsou databáze, e-mailové servery nebo vlastní doménové objekty a systémy.  Součástí začátků práce s WF4 bude zjištění základních aktivit, které byste mohli potřebovat nebo chcete při vytváření pracovních postupů.  Skvělou věcí je, že když vytváříte základní jednotky práce, můžete je kombinovat do hrubších odstupňovaných aktivit, které můžou vývojáři používat ve svých pracovních postupech. 

Hierarchie tříd aktivit

I když aktivita je aktivita aktivita, není pravda, že všechny aktivity mají stejné požadavky nebo potřeby.  Z tohoto důvodu je místo všech aktivit odvozených přímo z aktivity hierarchie základních tříd aktivit znázorněná na obrázku 30, ze které si můžete vybrat při vytváření vlastní aktivity. 

Obrázek 30: Hierarchie tříd aktivit

U většiny vlastních aktivit se buď odvozujete z AsyncCodeActivity, CodeActivity nebo NativeActivity (nebo jedné z obecných variant), nebo modelujete svou aktivitu deklarativním způsobem.  Na vysoké úrovni lze čtyři základní třídy popsat takto:

  • Aktivita – používá se k modelování aktivit vytvářením dalších aktivit, obvykle definovaných pomocí XAML.
  • CodeActivity – zjednodušená základní třída, když potřebujete napsat nějaký kód, aby se práce dokončila.
  • AsyncCodeActivity – používá se, když vaše aktivita provádí nějakou práci asynchronně.
  • NativeActivity – pokud vaše aktivita potřebuje přístup k interním modulům runtime, například k naplánování dalších aktivit nebo vytvoření záložek.

V následujících částech vytvořím několik aktivit, které vám pomohou zjistit, jak používat jednotlivé základní třídy.  Obecně platí, že když přemýšlíte o tom, kterou základní třídu použít, měli byste začít se základní třídou Aktivity a zjistit, jestli můžete vytvořit aktivitu pomocí deklarativní logiky, jak je znázorněno v další části.  V dalším kroku CodeActivity poskytuje zjednodušený model, pokud zjistíte, že je nutné napsat nějaký kód .NET k provedení úlohy a AsyncCodeActivity, pokud chcete, aby vaše aktivita byla spuštěna asynchronně.  A konečně, pokud píšete aktivity toku řízení, jako jsou aktivity nalezené v rámci (např. Switch, If), budete muset odvozovat ze základní třídy NativeActivity, aby bylo možné spravovat podřízené aktivity. 

Vytváření aktivit pomocí návrháře aktivit

Když vytvoříte nový projekt knihovny aktivit nebo když do projektu WF přidáte novou položku a vyberete šablonu Aktivita, získáte soubor XAML s prázdným prvkem Activity.  V návrháři se jedná o návrhovou plochu, kde můžete vytvořit tělo aktivity.  Pokud chcete začít s aktivitou, která bude mít více než jeden krok, obvykle pomáhá přetáhnout aktivitu sekvence jako tělo a poté ji naplnit logikou skutečné aktivity, protože tělo představuje jednu podřízenou aktivitu. 

Aktivitu si můžete představit podobně jako metodu u komponenty s argumenty.  U samotné aktivity můžete definovat argumenty spolu s jejich směrodatností, abyste definovali rozhraní aktivity.  Proměnné, které chcete použít v rámci aktivity, budou muset být definovány v aktivitách, které tvoří tělo, jako je kořenová sekvence, kterou jsem zmínil dříve.  Můžete například vytvořit aktivitu NotifyManager, která vytváří dvě jednodušší aktivity: GetManager a SendMail. 

Nejprve vytvořte nový projekt ActivityLibrary v sadě Visual Studio 2010 a přejmenujte soubor Activity1.xaml na NotifyManager.xaml.  Potom přetáhněte aktivitu sekvence z panelu nástrojů a přidejte ji do návrháře.  Jakmile je sekvence na místě, můžete ji naplnit podřízenými aktivitami, jak je znázorněno na obrázku 31. (Všimněte si, že aktivity použité v tomto příkladu jsou vlastními aktivitami v odkazovaném projektu a nejsou k dispozici v rámci architektury.)

obrázek 31: Upozornění na aktivity správce

Tato aktivita musí přijímat argumenty pro jméno zaměstnance a text zprávy. Aktivita GetManager vyhledá manažera zaměstnance a poskytne e-mail jako<řetězec OutArgument>.  Nakonec aktivita SendMail odešle manažeru zprávu.  Dalším krokem je definování argumentů aktivity rozbalením okna Argumenty v dolní části návrháře a zadáním informací pro dva požadované vstupní argumenty. 

Abyste mohli tyto položky vytvořit, musíte být schopni předat vstupní argumenty zadané v aktivitě NotifyManager jednotlivým podřízeným aktivitám.  Pro aktivitu GetManager potřebujete jméno zaměstnance, což je v argumentu aktivity. Název argumentu můžete použít v dialogovém okně vlastnosti pro argument employeeName v aktivitě GetManager, jak je vidět na obrázku 31.  Aktivita SendMail, potřebuje e-mailovou adresu manažera a zprávu.  Pro zprávu můžete zadat název argumentu obsahujícího zprávu.  Pro e-mailovou adresu však potřebujete způsob, jak předat argument z aktivity GetManager do argumentu pro aktivitu SendMail.  K tomu potřebujete proměnnou. 

Po zvýraznění aktivity Sequence můžete pomocí okna Variables definovat proměnnou s názvem "mgrEmail".  Nyní můžete tento název proměnné zadat jak pro argument ManagerEmail out v aktivitě GetManager, tak i do argumentu pro aktivitu SendMail.  Při spuštění aktivity GetManager budou výstupní data uložena v této proměnné a při spuštění aktivity SendMail se načtou data z této proměnné jako argumentu. 

Právě popsaný přístup je čistě deklarativní model pro definování těla aktivity.  V některých případech můžete chtít v kódu určit tělo aktivity.  Vaše aktivita může například obsahovat kolekci vlastností, které zase řídí sadu podřízených aktivit; Sada pojmenovaných hodnot, které řídí vytvoření sady aktivit Assign, by byla jedním z případů, kdy by bylo upřednostňované použití kódu.  V těchto případech můžete napsat třídu, která je odvozena z aktivity, a napsat kód ve vlastnosti Implementace vytvořit aktivitu (a všechny podřízené prvky), které představují funkce vaší aktivity.  Konečný výsledek je v obou případech stejný: logika je definována vytvářením dalších aktivit, pouze mechanismus, podle kterého je tělo definováno, je odlišné.  Obrázek 32 znázorňuje stejnou aktivitu NotifyManager definovanou v kódu. 

public class NotifyManager : Aktivita

{

    public InArgument<řetězec> EmployeeName { get; set; }

    public InArgument<řetězec> Zpráva { get; set; }

    ochrana přepsání func<aktivita> implementace

    {

        dostat

        {

            return () =>

            {

                Proměnná<řetězec> mgrEmail =

                new Variable<string> { Name = "mgrEmail" };

                Sekvence s = nová sekvence

                {

                    Proměnné = { mgrEmail },

                    Aktivity = {

                        new GetManager {

                            EmployeeName =

                                new VisualBasicValue<řetězec>("EmployeeName"),

                                Výsledek = mgrEmail,

                        },

                        new SendMail {

                            ToAddress = mgrEmail,

                            MailBody = new VisualBasicValue<řetězec>("Zpráva"),

                            From = "test@contoso.com",

                            Předmět = "Automatizovaný e-mail"

                        }

                    }

                };

                návrat s;

            };

        }

        set { base. Implementace = hodnota; }

    }

}

Obrázek 32: Složení aktivity pomocí kódu

Všimněte si, že základní třída je Activity a Implementační vlastnost je Func<Activity> k vrácení jedné aktivity. Tento kód je velmi podobný tomu, který se zobrazuje dříve při vytváření pracovních postupů a neměl by být překvapivý, protože cílem v obou případech je vytvoření aktivity.  Kromě toho je možné v argumentech přístupu kódu nastavit proměnné nebo můžete pomocí výrazů propojit jeden argument s druhým, jak je znázorněno pro argumenty EmployeeName a Message, jak se používají ve dvou podřízených aktivitách. 

Psaní vlastních tříd aktivit

Pokud zjistíte, že logiku vaší aktivity nelze dosáhnout vytvářením dalších aktivit, můžete napsat aktivitu založenou na kódu.  Při psaní aktivit v kódu, které odvozujete z příslušné třídy, definujte argumenty a pak přepište Execute metoda.  Metoda Execute se volá modulem runtime, když je čas, aby aktivita udělala svou práci.

Pokud chcete vytvořit aktivitu SendMail použitou v předchozím příkladu, musím nejprve zvolit základní typ.  I když je možné vytvořit funkce aktivity SendMail pomocí základní třídy Activity a vytváření TryCatch<T> a InvokeMethod aktivity, pro většinu vývojářů bude přirozenější zvolit mezi CodeActivity a NativeActivity základní třídy a psát kód pro logiku spouštění.  Vzhledem k tomu, že tato aktivita nepotřebuje vytvářet záložky nebo plánovat jiné aktivity, lze odvodit ze základní třídy CodeActivity.  Vzhledem k tomu, že tato aktivita vrátí jeden výstupní argument, měl by být odvozen od CodeActivity<TResult>, který poskytuje OutArgument<TResult>.  Prvním krokem je definování několika vstupních argumentů pro vlastnosti e-mailu.  Pak přepíšete metodu Execute, která implementuje funkce aktivity.  Obrázek 33 znázorňuje dokončenou třídu aktivity. 

public class SendMail: CodeActivity<SmtpStatusCode>

{

    public InArgument<řetězec> Do { get; set; }

    public InArgument<řetězec> From { get; set; }

    public InArgument<řetězec> Subject { get; set; }

    public InArgument<řetězec> Body { get; set; }

    protected override SmtpStatusCode Execute(

    Kontext CodeActivityContext)

    {

        zkusit

        {

            Klient SmtpClient = nový SmtpClient();

            klient. Odeslat(

            From.Get(context), ToAddress.Get(context),

            Subject.Get(context), MailBody.Get(context));

        }

        catch (SmtpException smtpException smtpEx)

        {

            return smtpEx.StatusCode;

        }

        return SmtpStatusCode.Ok;

    }

}

Obrázek 33: Vlastní aktivity SendMail

Použití argumentů je potřeba si poznamenat několik věcí.  Deklaroval jsem několik standardních vlastností .NET pomocí typů InArgument<T>.  Takto aktivita založená na kódu definuje své vstupní a výstupní argumenty.  V kódu však nemůžu jednoduše odkazovat na tyto vlastnosti získat hodnotu argumentu, potřebuji použít argument jako popisovač k načtení hodnoty pomocí zadané activityContext; v tomto případě CodeActivityContext.  K načtení hodnoty použijete metodu Get třídy argumentu a metodu Set pro přiřazení hodnoty k argumentu. 

Jakmile aktivita dokončí metodu Execute, modul runtime to zjistí a předpokládá, že aktivita je hotová a zavře ji.  Pro asynchronní nebo dlouho běžící práci existují způsoby, jak toto chování změnit, které jsou vysvětleny v nadcházející části, ale v tomto případě po odeslání e-mailu je práce dokončena. 

Teď pojďme prozkoumat aktivitu pomocí základní třídy NativeActivity ke správě podřízených aktivit.  Vytvořím aktivitu iterátoru, která provede nějakou podřízenou aktivitu za daný počet.  Nejprve potřebuji argument, který má obsahovat počet iterací, vlastnost aktivity, která se má provést, a proměnnou pro uložení aktuálního počtu iterací. Metoda Execute volá BeginIteration metoda ke spuštění počáteční iterace a následné iterace jsou vyvolány stejným způsobem.  Všimněte si na obrázku 34, že proměnné se manipulují stejným způsobem jako s argumenty pomocí metody Get a Set. 

Public Class Iterator : NativeActivity

{

    public Activity Body { get; set; }

    public InArgument<int> RequestedIterations { get; set; }

    veřejná proměnná<int> CurrentIteration { get; set; }

    public Iterator()

    {

        CurrentIteration = nová proměnná<int> { Default = 0 };

    }

    protected override void Execute(NativeActivityContext context)

    {

        BeginIteration(context);

    }

    private void BeginIteration(NativeActivityContext context)

    {

        if (RequestedIterations.Get(context) > CurrentIteration.Get(context))

        {

            kontext. ScheduleActivity(text,

            new CompletionCallback(ChildComplete),

            new FaultCallback(ChildFaulted));

        }

    }

}

Obrázek 34: Nativní aktivita iterátoru

Pokud se pozorně podíváte na BeginIteration metoda, všimnete si volání metody ScheduleActivity.  Takto může aktivita pracovat s modulem runtime a naplánovat další aktivitu pro spuštění, a je to proto, že tuto funkci potřebujete, abyste ji odvozovali z NativeActivity.  Všimněte si také, že při volání ScheduleActivity metody activityExecutionContext jsou k dispozici dvě metody zpětného volání.  Vzhledem k tomu, že nevíte, která aktivita se použije jako tělo nebo jak dlouho bude trvat dokončení, a protože WF je silně asynchronní programovací prostředí, používají se zpětná volání k upozornění vaší aktivity, když se dokončí podřízená aktivita, což vám umožní napsat kód, který bude reagovat.

Druhé zpětné volání je FaultCallback, který se vyvolá, pokud podřízená aktivita vyvolá výjimku.  V tomto zpětném volání obdržíte výjimku a máte možnost prostřednictvím ActivityFaultContext indikovat modulu runtime, že došlo k chybě, která ji udržuje od bublinového zvýrazňování a z aktivity. Obrázek 35 znázorňuje metody zpětného volání pro aktivitu Iterátoru, kde naplánuje další iteraci a FaultCallback zpracovává chybu, aby bylo možné pokračovat v další iteraci.

private void ChildComplete(NativeActivityContext context,

Instance ActivityInstance)

{

    CurrentIteration.Set(context; CurrentIteration.Get(context) + 1);

    BeginIteration(context);

}

private void ChildFaulted(NativeActivityFaultContext context, Exception ex,

Instance ActivityInstance)

{

    CurrentIteration.Set(context; CurrentIteration.Get(context) + 1);

    kontext. HandleFault();

}

Obrázek 35: Zpětná volání aktivit

Když vaše aktivita potřebuje udělat práci, která může být dlouhotrvající, v ideálním případě by se tato práce mohla předat jinému vláknu, aby bylo možné vlákno pracovního postupu použít k pokračování ve zpracování jiných aktivit nebo ke zpracování jiných pracovních postupů.  Stačí však spustit vlákna a vrátit řízení do modulu runtime může způsobit problémy, protože modul runtime nemonitoruje vlákna, která vytvoříte.  Pokud modul runtime zjistil, že pracovní postup byl nečinný, může se pracovní postup uvolnit, odstranit metody zpětného volání nebo modul runtime může předpokládat, že se vaše aktivita provádí, a přejít na další aktivitu v pracovním postupu.  Chcete-li podporovat asynchronní programování ve vaší aktivitě, odvozujete z AsyncCodeActivity nebo AsyncCodeActivity<T>. 

Obrázek 36 ukazuje příklad asynchronní aktivity, která načte informační kanál RSS.  Tento podpis metody execute se liší pro asynchronní aktivity v tom, že vrací IAsyncResult.  Do metody execute napíšete kód, který zahájí asynchronní operaci.  Po dokončení asynchronní operace přepište metodu EndExecute, která zpracuje zpětné volání a vrátí výsledek spuštění. 

veřejná zapečetěná třída GetFeed: AsyncCodeActivity<SyndicationFeed>

{

    public InArgument<Uri> FeedUrl { get; set; }

    protected override IAsyncResult BeginExecute(

    Kontext AsyncCodeActivityContext, zpětné volání AsyncCallback,

    stav objektu)

    {

        var req = (HttpWebRequest)HttpWebRequest.Create(

        FeedUrl.Get(context));

        Req. Method = "GET";

        kontext. UserState = req;

        return req. BeginGetResponse(new AsyncCallback(callback), state);

    }

    protected override SyndicationFeed EndExecute(

    Kontext AsyncCodeActivityContext, výsledek IAsyncResult)

    {

        HttpWebRequest req = context. UserState as HttpWebRequest;

        WebResponse wr = req. EndGetResponse(výsledek);

        SyndicationFeed localFeed = SyndicationFeed.Load(

        XmlReader.Create(wr. GetResponseStream());

        vrátit localFeed;

    }

}

Obrázek 36: Vytváření asynchronních aktivit

Další koncepty aktivit

Teď, když jste viděli základy vytváření aktivit pomocí základních tříd, argumentů a proměnných a správy provádění; Krátce se dotknu některých pokročilejších funkcí, které můžete použít při vývoji aktivit. 

Záložky umožňují autorovi aktivity vytvořit bod obnovení při provádění pracovního postupu.  Po vytvoření záložky je možné pokračovat ve zpracování pracovního postupu tam, kde skončila.  Záložky se ukládají jako součást stavu, takže na rozdíl od asynchronních aktivit se po vytvoření záložky nejedná o problém, kdy instance pracovního postupu zůstane trvalá a uvolněná.  Když hostitel chce pokračovat v pracovním postupu, načte instanci pracovního postupu a zavolá metodu ResumeBookmark, aby obnovil instanci tam, kde skončila.  Při obnovení záložek je možné data předat i do aktivity.   Obrázek 37 znázorňuje aktivitu ReadLine, která vytvoří záložku pro příjem vstupu a zaregistruje metodu zpětného volání, která se má vyvolat při doručení dat.  Modul runtime ví, kdy má aktivita nevyřízené záložky a nezavře aktivitu, dokud se záložka neobnoví.  ResumeBookmark metoda lze použít v WorkflowApplication třídy odeslat data do pojmenované záložky a signalizovat BookmarkCallback.  

public class ReadLine: NativeActivity<řetězec>

{

    public OutArgument<řetězec> InputText { get; set; }

    protected override void Execute(NativeActivityContext context)

    {

        kontext. CreateBookmark("ReadLine",

        new BookmarkCallback(BookmarkResumed));

    }

    private void BookmarkResumed(NativeActivityContext context,

        Záložka bk, stav objektu)

    {

        Result.Set(kontext, stav);

    }

}

Obrázek 37: Vytvoření záložky

Další výkonnou funkcí pro autory aktivit je koncept ActivityAction.  ActivityAction je ekvivalent pracovního postupu třídy Action v imperativním kódu: popis společného delegáta; ale u některých může být myšlenka šablony srozumitelnější.  Zvažte aktivitu ForEach<T>, která umožňuje iterovat sadu dat a naplánovat podřízenou aktivitu pro každou položku dat.  Potřebujete nějaký způsob, jak uživateli vaší aktivity umožnit definovat tělo a využívat datovou položku typu T. V podstatě potřebujete nějakou aktivitu, která může přijmout položku typu T a jednat s ní, aktivitaAction<T> se používá k povolení tohoto scénáře a poskytuje odkaz na argument a definici aktivity pro zpracování položky.  Pomocí ActivityAction můžete ve vlastních aktivitách povolit uživatelům vaší aktivity přidávat vlastní kroky v příslušných bodech.  Díky tomu můžete vytvořit šablony pracovního postupu nebo aktivit řazení, kde uživatel může vyplnit příslušné části a přizpůsobit tak provádění pro jejich použití.  Můžete také použít ActivityFunc<TResult> a související alternativy, když delegát, který vaše aktivita potřebuje vyvolat, vrátí hodnotu.  

Nakonec je možné ověřit aktivity, aby se zajistilo, že jsou správně nakonfigurované, kontrolou jednotlivých nastavení, omezením povolených podřízených aktivit atd. Pro běžnou potřebu vyžadovat konkrétní argument, můžete přidat RequiredArgument atribut do deklarace vlastnosti v aktivitě.  Pokud chcete více zapojit ověřování, vytvořte v konstruktoru vaší aktivity omezení a přidejte ho do kolekce omezení, která se zobrazí ve třídě Aktivita.  Omezení je aktivita zapsaná pro kontrolu cílové aktivity a zajištění platnosti.  Obrázek 38 znázorňuje konstruktor aktivity iterátoru, který ověřuje, že je nastavena vlastnost RequestedIterations. Nakonec přepsáním Metody CacheMetadata můžete vyvolat addValidationError metodu u parametru ActivityMetdata a přidat chyby ověřování pro vaši aktivitu. 

var act = new DelegateInArgument<Iterator> { Name = "constraintArg" };

var vctx = new DelegateInArgument<ValidationContext>();

Omezení<iterátoru> cons = new Constraint<Iterator>

{

    Body = new ActivityAction<Iterator, ValidationContext>

    {

        Argument1 = act,

        Argument2 = vctx,

        Obslužná rutina = nová AssertValidation

        {

            Message = "Iteration must be provided",

            PropertyName = "RequestedIterations",

            Assertion = new InArgument<bool>(

                e) => akt. Get(e). RequestedIterations != null)

        }

    }

};

základna. Constraints.Add(cons);

Obrázek 38: Omezení

Návrháři aktivit

Jednou z výhod WF je, že umožňuje programovat logiku aplikace deklarativním způsobem, ale většina lidí nechce psát XAML ručně, což je důvod, proč je prostředí návrháře ve WF tak důležité.  Při vytváření vlastních aktivit budete také pravděpodobně chtít vytvořit návrháře, který uživatelům vaší aktivity poskytne prostředí pro zobrazení a vizuální interakci.  Návrhář pro WF je založený na windows Presentation Foundation, což znamená, že máte všechny možnosti stylů, triggerů, datovou vazbu a všechny další skvělé nástroje pro vytvoření bohatého uživatelského rozhraní pro vašeho návrháře.  WF navíc poskytuje některé uživatelské ovládací prvky, které můžete použít v návrháři, aby se zjednodušilo zobrazení jednotlivých podřízených aktivit nebo kolekce aktivit.  Čtyři primární ovládací prvky jsou:

  • ActivityDesigner – kořenový ovládací prvek WPF používaný v návrhářích aktivit
  • WorkflowItemPresenter – slouží k zobrazení jedné aktivity
  • WorkflowItemsPresenter – slouží k zobrazení kolekce podřízených aktivit
  • ExpressionTextBox – slouží k povolení úprav výrazů, jako jsou argumenty

WF4 obsahuje šablonu projektu ActivityDesignerLibrary a šablonu položky ActivityDesigner, kterou lze použít k počátečnímu vytvoření artefaktů.  Jakmile inicializujete návrháře, můžete začít používat výše uvedené prvky k přizpůsobení vzhledu a chování vaší aktivity rozložením zobrazení dat a vizuální reprezentace podřízených aktivit.  V návrháři máte přístup k ModelItem, který je abstrakcí nad skutečnou aktivitou a zobrazí se všechny vlastnosti aktivity. 

Ovládací prvek WorkflowItemPresenter lze použít k zobrazení jedné aktivity, která je součástí vaší aktivity.  Pokud chcete například poskytnout možnost přetáhnout aktivitu na aktivitu iterátoru zobrazenou dříve a zobrazit aktivitu obsaženou v aktivitě Iteractoru, můžete použít XAML zobrazený na obrázku 39 a vytvořit vazbu WorkflowItemPresenter na ModelItem.Body.  Obrázek 40 znázorňuje návrháře, který se používá na návrhové ploše pracovního postupu . 

<sap:ActivityDesigner x:Class="CustomActivities.Presentation.IteratorDesigner"

  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:sap="clr-namespace:System.Activities.Presentation;

assembly=System.Activities.Presentation"

  xmlns:sapv="clr-namespace:System.Activities.Presentation.View;

assembly=System.Activities.Presentation">

  > mřížky <

    <Border BorderBrush="MidnightBlue" BorderThickness="3" CornerRadius="10">

<sap:WorkflowItemPresenter MinHeight="50"

Item="{Binding Path=ModelItem.Body, Mode=TwoWay}"

HintText="Přidat text sem" />

    </Border>

  </Grid>

</sap:ActivityDesigner>

Obrázek 39: WorkflowItemPresenter v návrháři aktivit

Obrázek 40: Návrhář iterátoru

WorkflowItemsPresenter poskytuje podobné funkce pro zobrazení více položek, jako jsou podřízené položky v posloupnosti. Můžete definovat šablonu a orientaci pro to, jak chcete zobrazit položky, a také šablonu mezerník pro přidání vizuálních prvků mezi aktivity, jako jsou spojnice, šipky nebo něco zajímavějšího.  Obrázek 41 ukazuje jednoduchý návrhář pro vlastní sekvenci aktivity, která zobrazuje podřízené aktivity s vodorovnou čárou mezi jednotlivými aktivitami.

<sap:ActivityDesigner x:Class="CustomActivities.Presentation.CustomSequenceDesigner"

    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:sap="clr-namespace:System.Activities.Presentation;

assembly=System.Activities.Presentation"

    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;

assembly=System.Activities.Presentation">

    > mřížky <

      < > StackPanel

         <Border BorderBrush="Goldenrod" BorderThickness="3">

     <sap:WorkflowItemsPresenter HintText="Drop Activities Here"

  Items="{Binding Path=ModelItem.ChildActivities}">

     <sap:WorkflowItemsPresenter.SpacerTemplate>

  > <DataTemplate

    <Výška obdélníku="3" Width="40"

 Fill="MidnightBlue" Margin="5" />

                     </DataTemplate>

                  </sap:WorkflowItemsPresenter.SpacerTemplate>

                  <sap:WorkflowItemsPresenter.ItemsPanel>

                      <ItemsPanelTemplate>

                          <StackPanel Orientation="Vertical"/>

                      </ItemsPanelTemplate>

                   </sap:WorkflowItemsPresenter.ItemsPanel>

            </sap:WorkflowItemsPresenter>

        </Border>

      </StackPanel>

    </Grid>

</sap:ActivityDesigner>

Obrázek 41: Návrhář vlastní sekvence pomocí WorkflowItemsPresenter

Obrázek 42: Návrhář sekvence

Nakonec ovládací prvek ExpressionTextBox umožňuje místní úpravy argumentů aktivity v návrháři kromě mřížky vlastností. V sadě Visual Studio 2010 to zahrnuje podporu intellisense pro zadané výrazy. Obrázek 43 znázorňuje návrháře aktivity GetManager vytvořené dříve, což umožňuje úpravy argumentů EmployeeName a ManagerEmail v návrháři. Skutečný návrhář se zobrazuje na obrázku 44. 

<sap:ActivityDesigner x:Class="CustomActivities.Presentation.GetManagerDesigner"

    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:sap="clr-namespace:System.Activities.Presentation;

assembly=System.Activities.Presentation"

    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;

assembly=System.Activities.Presentation"

xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;

assembly=System.Activities.Presentation">

    <sap:ActivityDesigner.Resources>

        <sapc:ArgumentToExpressionConverter

x:Key="ArgumentToExpressionConverter"

x:Uid="swdv:ArgumentToExpressionConverter_1" />

    </sap:ActivityDesigner.Resources>

    > mřížky <

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="50" />

             <ColumnDefinition Width="*" />

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition />

            <RowDefinition />

            <RowDefinition />

        </Grid.RowDefinitions>

        <TextBlock VerticalAlignment="Center"

 HorizontalAlignment="Center">Employee:</TextBlock>

        <sapv:ExpressionTextBox Grid.Column="1"

              Expression="{Binding Path=ModelItem.EmployeeName, Mode=TwoWay,

       Converter={StaticResource ArgumentToExpressionConverter},

       ConverterParameter=In}" OwnerActivity="{Binding Path=ModelItem}"

MinLines="1" MaxLines="1" MinWidth="50"

HintText="< Jméno zaměstnance>" />

        <TextBlock Grid.Row="1" VerticalAlignment="Center"

              HorizontalAlignment="Center">Mgr Email:</TextBlock>

        <sapv:ExpressionTextBox Grid.Column="2" Grid.Row="1"

    UseLocationExpression="True"

           Expression="{Binding Path=ModelItem.ManagerEmail, Mode=TwoWay,

    Converter={StaticResource ArgumentToExpressionConverter},

    ConverterParameter=Out}" OwnerActivity="{Binding Path=ModelItem}"

    MinLines="1" MaxLines="1" MinWidth="50" />

    </Grid>

</sap:ActivityDesigner>

Obrázek 43: Úprava argumentů v návrháři pomocí expressionTextBoxu

Obrázek 44: Návrhář aktivity GetManager

Ukázkoví návrháři, které zde uvádíme, byly jednoduché zvýraznit konkrétní funkce, ale plný výkon WPF je k dispozici, aby vaše aktivity byly jednodušší konfigurovat a přirozeněji používat pro uživatele.   Po vytvoření návrháře existují dva způsoby, jak ho přidružit k aktivitě: použití atributu na třídu aktivity nebo implementaci rozhraní IRegisterMetadata.  Pokud chcete, aby definice aktivity řídila volbu návrháře, jednoduše použijte NávrhářAttribute na třídu aktivity a zadejte typ návrháře; to funguje přesně stejně jako ve WF3.  Pro volně svázanější implementaci můžete implementovat IRegisterMetadata rozhraní a definovat atributy, které chcete použít pro třídu a vlastnosti aktivity.  Obrázek 45 ukazuje ukázkovou implementaci pro použití návrhářů pro dvě vlastní aktivity. Visual Studio zjistí vaši implementaci a automaticky ji vyvolá, zatímco vlastní hostitel návrháře, probíraný dále, zavolá metodu explicitně.

metadata veřejné třídy: IRegisterMetadata

{

    public void Register()

    {

        AttributeTableBuilder builder = new AttributeTableBuilder();

        budovatel. AddCustomAttributes(typeof(SendMail), nový atribut[] {

            new DesignerAttribute(typeof(SendMailDesigner))});

        budovatel. AddCustomAttributes(typeof(GetManager), nový atribut[]{

            new DesignerAttribute(typeof(GetManagerDesigner))});

        MetadataStore.AddAttributeTable(builder. CreateTable());

    }

}

Obrázek 45: Registrace návrhářů pro aktivity

Změna hostitele návrháře pracovního postupu

V minulosti vývojáři často chtěli svým uživatelům poskytnout možnost vytvářet nebo upravovat pracovní postupy.  V předchozích verzích Windows Workflow Foundation to bylo možné, ale ne triviální úkol.  S přechodem na WPF přichází nový návrhář a změna hostitele byla základním případem použití pro vývojový tým.  Návrháře můžete hostovat ve vlastní aplikaci WPF, jako je znázorněná na obrázku 46 s několika řádky kódu XAML a několika řádky kódu. 

Obrázek 46: Návrhář pracovních postupů pře hostovaný

XAML pro okno, obrázek 47, používá mřížku k rozložení tří sloupců a poté umístí ovládací prvek ohraničení do každé buňky.  V první buňce se sada nástrojů vytvoří deklarativním způsobem, ale dá se také vytvořit v kódu.  Pro samotné zobrazení návrháře a mřížku vlastností jsou ve všech zbývajících buňkách dva prázdné ovládací prvky ohraničení.  Tyto ovládací prvky se přidají do kódu. 

okno <x:Class="WorkflowEditor.MainWindow"

        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:sys="clr-namespace:System; assembly=mscorlib"

 xmlns:sapt="clr-namespace:System.Activities.Presentation.Toolbox;

assembly=System.Activities.Presentation"

        Title="Editor pracovního postupu" Height="500" Width="700" >

    > window.resources <

        <sys:String x:Key="AssemblyName">System.Activities, Version=4.0.0.0,

Culture=neutral, PublicKeyToken=31bf3856ad364e35</sys:String>

        <sys:String x:Key="MyAssemblyName">CustomActivities</sys:String>

    </Window.Resources>

    <Grid x:Name="DesignerGrid">

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="2*" />

            <ColumnDefinition Width="7*" />

            <ColumnDefinition Width="3*" />

        </Grid.ColumnDefinitions>

        <border>

            <sapt:ToolboxControl>

                <sapt:ToolboxControl.Categories>

                    <sapt:ToolboxCategory CategoryName="Basic">

                        <sapt:ToolboxItemWrapper

  AssemblyName="{StaticResource AssemblyName}" >

                            <sapt:ToolboxItemWrapper.ToolName>

                                System.Activities.Statements.Sequence

                            </sapt:ToolboxItemWrapper.ToolName>

                        </sapt:ToolboxItemWrapper>

                        <sapt:ToolboxItemWrapper

AssemblyName="{StaticResource MyAssemblyName}">

                            <sapt:ToolboxItemWrapper.ToolName>

                                CustomActivities.SendMail

                             </sapt:ToolboxItemWrapper.ToolName>

                        </sapt:ToolboxItemWrapper>

                    </sapt:ToolboxCategory>

                </sapt:ToolboxControl.Categories>

            </sapt:ToolboxControl>

        </Border>

        <Border Name="DesignerBorder" Grid.Column="1"

BorderBrush="Salmon" BorderThickness="3" />

        <Border x:Name="PropertyGridExpander" Grid.Column="2" />

    </Grid>

</Window>

Obrázek 47: Návrhář přehostuje XAML

Kód pro inicializaci návrháře a mřížky vlastností je znázorněn na obrázku 48.  Prvním krokem v metodě OnInitialized je registrace návrhářů pro všechny aktivity, které budou použity v návrháři pracovního postupu.  Třída DesignerMetadata registruje přidružené návrháře pro aktivity, které jsou dodávány s architekturou a třída Metadata registruje návrháře pro mé vlastní aktivity.  Dále vytvořte WorkflowDesigner třídy a pomocí View a PropertyInspectorView vlastnosti pro přístup k UIElement objekty potřebné k vykreslení.  Návrhář se inicializuje s prázdnou sekvencí, ale můžete také přidat nabídky a načíst XAML pracovního postupu z různých zdrojů, včetně systému souborů nebo databáze. 

public MainWindow()

{

    InitializeComponent();

}

protected override void OnInitialized(EventArgs e) {

    základna. OnInitialized(e);

    RegisterDesigners();

    PlaceDesignerAndPropGrid();

}

private void RegisterDesigners() {

    new DesignerMetadata(). Register();

    new CustomActivities.Presentation.Metadata(). Register();

}

private void PlaceDesignerAndPropGrid() {

    Návrhář WorkflowDesigner = nový WorkflowDesigner();

    návrhář. Load(new System.Activities.Statements.Sequence());

    DesignerBorder.Child = designer. Pohled;

    PropertyGridExpander.Child = designer. PropertyInspectorView;

}

Obrázek 48: Změna hostitele kódu návrháře

Pomocí tohoto malého kusu kódu a revizí můžete upravit pracovní postup, přetáhnout aktivity z panelu nástrojů, nakonfigurovat proměnné v pracovním postupu a manipulovat s argumenty u aktivit.  Text XAML můžete získat také voláním Flush v návrháři a odkazováním na Text vlastnost WorkflowDesigner.  Existuje mnohem více, co můžete udělat a začínáme je mnohem jednodušší než předtím. 

Služby pracovních postupů

Jak už bylo zmíněno dříve, jednou z velkých oblastí zaměření v této verzi Windows Workflow Foundation je užší integrace se službou Windows Communication Foundation.  Příklad v názorném postupu aktivity ukázal, jak volat službu z pracovního postupu, a v této části proberem, jak zveřejnit pracovní postup jako službu WCF. 

Začněte tím, že vytvoříte nový projekt a vyberete projekt služby pracovního postupu WCF. Po dokončení šablony najdete projekt s web.config souborem a souborem s příponou XAMLX.  Soubor XAMLX je deklarativní služba nebo služba pracovního postupu a podobně jako jiné šablony WCF poskytuje funkční, i když jednoduchou implementaci služby, která přijímá požadavek a vrací odpověď.  V tomto příkladu změním smlouvu tak, aby vytvořila operaci pro příjem vyúčtování výdajů a vrátila indikátor, že byla sestava přijata.  Začněte tak, že do projektu přidáte třídu ExpenseReport, jako je třída zobrazená na obrázku 49.

[DataContract]

public class ExpenseReport

{

    [DataMember]

    public DateTime FirstDateOfTravel { get; set; }

    [DataMember]

    public double TotalAmount { get; set; }

    [DataMember]

    public string EmployeeName { get; set; }

}

Obrázek 49: Typ smlouvy vyúčtování výdajů

Zpátky v návrháři pracovního postupu změňte typ proměnné "data" v proměnných na právě definovaný typ ExpenseReport (možná budete muset vytvořit projekt pro typ, aby se zobrazil v dialogovém okně pro výběr typu). Aktualizujte aktivitu Příjmu kliknutím na tlačítko Obsah a změnou typu v dialogovém okně na typ ExpenseReport tak, aby odpovídal.  Aktualizujte vlastnosti aktivity tak, aby definovaly nový OperationName a ServiceContractName, jak je znázorněno na obrázku 50. 

Obrázek 50: Konfigurace umístění příjmu

Nyní aktivita SendReply může mít hodnotu nastavenou na True pro vrácení indikátoru příjmu.  Samozřejmě, v složitější ukázce byste před určením odpovědi mohli pomocí plného výkonu pracovního postupu ukládat informace do databáze, provádět ověření sestavy atd. Přechod na službu pomocí aplikace WCFTestClient ukazuje, jak konfigurace aktivity definuje vystavený kontrakt služby, jak je znázorněno na obrázku 51. 

Obrázek 51: Kontrakt vygenerovaný ze služby pracovního postupu

Jakmile vytvoříte službu pracovního postupu, musíte ji hostovat stejně jako jakoukoli službu WCF.  Předchozí příklad použil nejjednodušší možnost pro hostování služby IIS.  Chcete-li hostovat službu pracovního postupu ve vlastním procesu, budete chtít použít WorkflowServiceHost třídy nalezené v sestavení System.ServiceModel.Activities.  Všimněte si, že v sestavení System.WorkflowServices existuje jiná třída se stejným názvem, která se používá k hostování služeb pracovních postupů vytvořených pomocí aktivit WF3.  V nejjednodušším případě samoobslužného hostování můžete k hostování služby a přidání koncových bodů použít kód podobný jako na obrázku 52. 

Hostitel WorkflowServiceHost = nový

    WorkflowServiceHost(XamlServices.Load("ExpenseReportService.xamlx"),

    new Uri("https://localhost:9897/Services/Expense"));

hostitel. AddDefaultEndpoints();

hostitel. Description.Behaviors.Add(

    new ServiceMetadataBehavior { HttpGetEnabled = true });

hostitel. Open();

Console.WriteLine("Hostitel je otevřen");

Console.ReadLine();

Obrázek 52: Samoobslužné hostování služby pracovního postupu

Pokud chcete využívat možnosti spravovaného hostování ve Windows, můžete službu hostovat ve službě IIS zkopírováním souboru XAMLX do adresáře a zadáním jakýchkoli nezbytných konfiguračních informací pro chování, vazby, koncové body atd. v souboru web.config.  Ve skutečnosti, jak jsme viděli dříve, když vytvoříte nový projekt v sadě Visual Studio pomocí jedné ze šablon projektů deklarativní služby pracovních postupů, získáte projekt se souborem web.config a službou pracovního postupu definovanou v XAMLX, která je připravená k nasazení. 

Při použití Třídy WorkflowServiceHost k hostování služby pracovního postupu stále musíte být schopni konfigurovat a řídit instance pracovního postupu.  K řízení služby existuje nový standardní koncový bod s názvem WorkflowControlEndpoint.  Doprovodná třída WorkflowControlClient poskytuje předem sestavený klientský proxy server .  Ve službě můžete zveřejnit WorkFlowControlEndpoint a pomocí WorkflowControlClient můžete vytvářet a spouštět nové instance pracovních postupů nebo řídit spuštěné pracovní postupy.  Stejný model používáte ke správě služeb na místním počítači nebo ho můžete použít ke správě služeb na vzdáleném počítači.  Obrázek 53 ukazuje aktualizovaný příklad zveřejnění koncového bodu řízení pracovního postupu ve vaší službě. 

Hostitel WorkflowServiceHost = nový

    WorkflowServiceHost("ExpenseReportService.xamlx",

    new Uri("https://localhost:9897/Services/Expense"));

hostitel. AddDefaultEndpoints();

WorkflowControlEndpoint wce = new WorkflowControlEndpoint(

    new NetNamedPipeBinding(),

    new EndpointAddress("net.pipe://localhost/Expense/WCE"));

hostitel. AddServiceEndpoint(wce);

hostitel. Open();

Obrázek 53: Koncový bod řízení pracovního postupu

Vzhledem k tomu, že nevytvořujete přímo instance WorkflowInstance, existují dvě možnosti pro přidání rozšíření do modulu runtime.  První je, že můžete přidat některá rozšíření do WorkflowServiceHost a inicializují se správně s vašimi instancemi pracovního postupu.  Druhá používá konfiguraci.  Sledovací systém může být například zcela definován v konfiguračním souboru aplikace.   Definujete účastníky sledování a profily sledování v konfiguračním souboru a pomocí chování použijete konkrétního účastníka na službu, jak je znázorněno na obrázku 54. 

<system.serviceModel>

    > sledování <

      > účastníky <

        <add name="EtwTrackingParticipant"

             type="System.Activities.Tracking.EtwTrackingParticipant, System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

             profileName="HealthMonitoring_Tracking_Profile"/>

      </participants>

      profily <>

        <trackingProfile name="HealthMonitoring_Tracking_Profile">

          <activityDefinitionId="*">

            <workflowInstanceQuery>

              <stavy>

                <state name="Started"/>

                <state name="Completed"/>

              </states>

            </workflowInstanceQuery>

          </workflow>

        </trackingProfile>

      </profiles>

</tracking>

. . .

<chování>

      <serviceBehaviors>

        <behavior name="SampleTrackingSample.SampleWFBehavior">

          <etwTracking profileName=" HealthMonitoring_Tracking_Profile" />

        </behavior>

      </serviceBehaviors>

</behaviors>

. . .

Obrázek 54: Konfigurace sledování pro služby

Existuje mnoho nových vylepšení hostování a konfigurace služeb WCF, které můžete využít ve svých pracovních postupech, jako jsou služby ".svc-less", nebo služby, které nepotřebují příponu souboru, výchozí vazby a výchozí koncové body, jen abyste mohli pár pojmenovat.  Další informace o těchto a dalších funkcích wcf4 najdete v doprovodné dokumentaci k WCF nalezené v části Další zdroje informací. 

Kromě vylepšení hostování technologie Windows Workflow Foundation využívá další funkce wcf; někteří přímo a jiní nepřímo.  Korelace zpráv je teď klíčovou funkcí při vytváření služeb, která umožňuje spojit zprávy s danou instancí pracovního postupu na základě dat ve zprávě, jako je číslo objednávky nebo ID zaměstnance. Korelaci je možné nakonfigurovat pro různé aktivity zasílání zpráv pro požadavek i odpověď a podporuje korelaci s více hodnotami ve zprávě.  Další podrobnosti o těchto nových funkcích najdete v doprovodné dokumentaci k WCF4.   

Závěr

Nová technologie Windows Workflow Foundation, která se dodává s rozhraním .NET Framework 4, představuje významné zlepšení výkonu a produktivity vývojářů a uvědomuje si cíl deklarativního vývoje aplikací pro obchodní logiku.  Architektura poskytuje nástroje pro krátké jednotky složité práce, které je potřeba zjednodušit, a pro vytváření složitých dlouhotrvajících služeb s korelovanými zprávami, trvalým stavem a bohatým přehledem aplikací prostřednictvím sledování. 

O autorovi

Matt je členem technického personálu v Pluralsightu, kde se zaměřuje na technologie propojených systémů (WCF, WF, BizTalk, AppFabric a platforma služeb Azure). Matt je také nezávislý konzultant specializující se na návrh a vývoj aplikací Microsoft .NET. Jako spisovatel Matt přispěl do několika časopisů a časopisů, včetně MSDN Magazine, kde v současné době autory pracovního postupu pro sloupec Foundations. Matt pravidelně sdílí svou lásku k technologiím tím, že mluví na místních, regionálních a mezinárodních konferencích, jako je Tech Ed. Microsoft poznal Matta jako MVP pro své komunitní příspěvky týkající se technologií propojených systémů. Kontaktujte Matta prostřednictvím svého blogu: http://www.pluralsight.com/community/blogs/matt/default.aspx.

Další zdroje informací