Delen via


Activiteitsdelegen gebruiken

Met activiteitsdelegaties kunnen auteurs van activiteiten callbacks beschikbaar maken met specifieke handtekeningen, waarvoor gebruikers van de activiteit handlers op basis van activiteiten kunnen bieden. Er zijn twee soorten activiteitsdelegeringen beschikbaar: ActivityAction<T> wordt gebruikt om activiteitsdelegeringen te definiëren die geen retourwaarde hebben en ActivityFunc<TResult> wordt gebruikt om activiteitsdelegeringen te definiëren die wel een retourwaarde hebben.

Activiteitsdelegen zijn handig in scenario's waarin een onderliggende activiteit moet worden beperkt tot een bepaalde handtekening. Een While activiteit kan bijvoorbeeld elk type onderliggende activiteit bevatten zonder beperkingen, maar de hoofdtekst van een ForEach<T> activiteit is een ActivityAction<T>, en de onderliggende activiteit die uiteindelijk wordt uitgevoerd door ForEach<T> een InArgument<T> die hetzelfde type leden van de verzameling is dat de ForEach<T> opsomming bevat.

ActivityAction gebruiken

Verschillende .NET Framework 4.6.1-activiteiten maken gebruik van activiteitsacties, zoals de Catch activiteit en de ForEach<T> activiteit. In elk geval vertegenwoordigt de activiteitsactie een locatie waar de auteur van de werkstroom een activiteit opgeeft die het gewenste gedrag aangeeft bij het opstellen van een werkstroom met behulp van een van deze activiteiten. In het volgende voorbeeld wordt een ForEach<T> activiteit gebruikt om tekst weer te geven in het consolevenster. De hoofdtekst van de tekst ForEach<T> wordt opgegeven met behulp van een ActivityAction<T> tekenreeks die overeenkomt met het type ForEach<T> tekenreeks. De WriteLine activiteit die in de Handler activiteit is opgegeven, heeft het Text argument gebonden aan de tekenreekswaarden in de verzameling die door de ForEach<T> activiteit wordt herhaald.

DelegateInArgument<string> actionArgument = new DelegateInArgument<string>();

Activity wf = new ForEach<string>
{
    Body = new ActivityAction<string>
    {
        Argument = actionArgument,
        Handler = new WriteLine
        {
            Text = new InArgument<string>(actionArgument)
        }
    }
};

List<string> items = new List<string>();
items.Add("Hello");
items.Add("World.");

Dictionary<string, object> inputs = new Dictionary<string, object>();
inputs.Add("Values", items);

WorkflowInvoker.Invoke(wf, inputs);

De actionArgument wordt gebruikt om de afzonderlijke items in de verzameling naar de WriteLine te laten stromen. Wanneer de werkstroom wordt aangeroepen, wordt de volgende uitvoer weergegeven in de console.

HelloWorld.

In de voorbeelden in dit onderwerp wordt de syntaxis van objectitialisatie gebruikt. De syntaxis van object initialisatie kan een handige manier zijn om werkstroomdefinities in code te maken, omdat deze een hiërarchische weergave biedt van de activiteiten in de werkstroom en de relatie tussen de activiteiten weergeeft. Er is geen vereiste om de syntaxis van object initialisatie te gebruiken wanneer u programmatisch werkstromen maakt. Het volgende voorbeeld is functioneel gelijk aan het vorige voorbeeld.

DelegateInArgument<string> actionArgument = new DelegateInArgument<string>();

WriteLine output = new WriteLine();
output.Text = new InArgument<string>(actionArgument);

ActivityAction<string> body = new ActivityAction<string>();
body.Argument = actionArgument;
body.Handler = output;

ForEach<string> wf = new ForEach<string>();
wf.Body = body;

List<string> items = new List<string>();
items.Add("Hello");
items.Add("World.");

Dictionary<string, object> inputs = new Dictionary<string, object>();
inputs.Add("Values", items);

WorkflowInvoker.Invoke(wf, inputs);

Zie Voor meer informatie over objectinitialisaties : Objecten initialiseren zonder een constructor aan te roepen (C#-programmeerhandleiding) en instructies: een object declareren met behulp van een Object Initializer (Visual Basic).

In het volgende voorbeeld wordt een TryCatch activiteit gebruikt in een werkstroom. Een ApplicationException wordt gegenereerd door de werkstroom en wordt verwerkt door een Catch<TException> activiteit. De handler voor de activiteitsactie van de Catch<TException> activiteit is een WriteLine activiteit en de uitzonderingsdetails worden doorgestroomd met behulp van de exDelegateInArgument<T>.

DelegateInArgument<ApplicationException> ex = new DelegateInArgument<ApplicationException>()
{
    Name = "ex"
};

Activity wf = new TryCatch
{
    Try = new Throw()
    {
        Exception = new InArgument<Exception>((env) => new ApplicationException("An ApplicationException was thrown."))
    },
    Catches =
    {
        new Catch<ApplicationException>
        {
            Action = new ActivityAction<ApplicationException>
            {
                Argument = ex,
                Handler = new WriteLine()
                {
                    Text = new InArgument<string>((env) => ex.Get(env).Message)
                }
            }
        }
    },
    Finally = new WriteLine()
    {
        Text = "Executing in Finally."
    }
};

Wanneer u een aangepaste activiteit maakt die een ActivityAction<T>definieert, gebruikt u een InvokeAction<T> om de aanroep van die ActivityAction<T>activiteit te modelleren. In dit voorbeeld wordt een aangepaste WriteLineWithNotification activiteit gedefinieerd. Deze activiteit bestaat uit een Sequence activiteit die een WriteLine activiteit bevat, gevolgd door een InvokeAction<T> activiteit die een ActivityAction<T> tekenreeksargument aanroept.

public class WriteLineWithNotification : Activity
{
    public InArgument<string> Text { get; set; }
    public ActivityAction<string> TextProcessedAction { get; set; }

    public WriteLineWithNotification()
    {
        this.Implementation = () => new Sequence
        {
            Activities =
            {
                new WriteLine
                {
                    Text = new InArgument<string>((env) => Text.Get(env))
                },
                new InvokeAction<string>
                {
                    Action = TextProcessedAction,
                    Argument = new InArgument<string>((env) => Text.Get(env))
                }
            }
        };
    }
}

Wanneer een werkstroom wordt gemaakt met behulp van de WriteLineWithNotification activiteit, geeft de auteur van de werkstroom de gewenste aangepaste logica op in de activiteitenactie Handler. In dit voorbeeld wordt een werkstroom gemaakt die gebruikmaakt van de WriteLineWithNotification activiteit en een WriteLine activiteit wordt gebruikt als de Handler.

// Create and invoke the workflow without specifying any activity action
// for TextProcessed.
Activity wf = new WriteLineWithNotification
{
    Text = "Hello World."
};

WorkflowInvoker.Invoke(wf);

// Output:
// Hello World.

// Create and Invoke the workflow with specifying an activity action
// for TextProcessed.
DelegateInArgument<string> msg = new DelegateInArgument<string>();
Activity wf2 = new WriteLineWithNotification
{
    Text = "Hello World with activity action.",
    TextProcessedAction = new ActivityAction<string>
    {
        Argument = msg,
        Handler = new WriteLine
        {
            Text = new InArgument<string>((env) => "Handler of: " + msg.Get(env))
        }
    }
};

// Invoke the workflow with an activity action specified
WorkflowInvoker.Invoke(wf2);

// Output:
// Hello World with activity action.
// Handler of: Hello World with activity action.

Er zijn meerdere algemene versies van en InvokeAction<T> opgegeven voor het doorgeven van ActivityAction<T> een of meer argumenten.

ActivityFunc gebruiken

ActivityAction<T> is handig wanneer er geen resultaatwaarde van de activiteit is en ActivityFunc<TResult> wordt gebruikt wanneer een resultaatwaarde wordt geretourneerd. Wanneer u een aangepaste activiteit maakt die een ActivityFunc<TResult>definieert, gebruikt u een InvokeFunc<TResult> om de aanroep van die ActivityFunc<TResult>activiteit te modelleren. In het volgende voorbeeld wordt een WriteFillerText activiteit gedefinieerd. Als u de opvultekst wilt opgeven, wordt een InvokeFunc<TResult> opgegeven dat een geheel getal gebruikt en een tekenreeksresultaat heeft. Zodra de opvultekst is opgehaald, wordt deze weergegeven in de console met behulp van een WriteLine activiteit.

public class WriteFillerText : Activity
{
    public ActivityFunc<int, string> GetText { get; set; }
    public InArgument<int> Quantity { get; set; }

    Variable<string> text = new Variable<string>
    {
        Name = "Text"
    };

    public WriteFillerText()
    {
        this.Implementation = () => new Sequence
        {
            Variables =
            {
                text
            },
            Activities =
            {
                new InvokeFunc<int, string>
                {
                    Func = GetText,
                    Argument = new InArgument<int>((env) => Quantity.Get(env)),
                    Result = new OutArgument<string>(text)
                },
                new WriteLine
                {
                    Text = new InArgument<string>(text)
                }
            }
        };
    }
}

Als u de tekst wilt opgeven, moet een activiteit worden gebruikt die één int argument gebruikt en een tekenreeksresultaat heeft. In dit voorbeeld ziet u een TextGenerator activiteit die aan deze vereisten voldoet.

public class TextGenerator : CodeActivity<string>
{
    public InArgument<int> Quantity { get; set; }
    public InArgument<string> Text { get; set; }

    protected override string Execute(CodeActivityContext context)
    {
        // Provide a quantity of Random Text
        int q = Quantity.Get(context);
        if (q < 1)
        {
            q = 1;
        }

        string text = Text.Get(context) + " ";
        StringBuilder sb = new StringBuilder(text.Length * q);
        for (int i = 0; i < q; i++)
        {
            sb.Append(text);
        }

        return sb.ToString();
    }
}

Als u de TextGenerator activiteit met de activiteit wilt gebruiken, geeft u deze WriteFillerText op als de Handler.

DelegateInArgument<int> actionArgument = new DelegateInArgument<int>();

Activity wf = new WriteFillerText
{
    Quantity = 5,
    GetText = new ActivityFunc<int, string>
    {
        Argument = actionArgument,
        Handler = new TextGenerator
        {
            Quantity = new InArgument<int>(actionArgument),
            Text = "Hello World."
        }
    }
};

WorkflowInvoker.Invoke(wf);