Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Delegáti aktivit umožňují autorům aktivit zveřejnit zpětná volání s určitými podpisy, pro které mohou uživatelé aktivity poskytovat obslužné rutiny založené na aktivitách. K dispozici jsou dva typy delegátů aktivit: ActivityAction<T> slouží k definování delegátů aktivit, které nemají návratovou hodnotu, a ActivityFunc<TResult> slouží k definování delegátů aktivity, které mají návratovou hodnotu.
Delegáti aktivit jsou užitečné ve scénářích, kdy musí být podřízená aktivita omezena na určitý podpis. Aktivita může například While obsahovat libovolný typ podřízené aktivity bez omezení, ale tělo ForEach<T> aktivity je aktivita ActivityAction<T>a podřízená aktivita, která je nakonec spuštěna ForEach<T> , musí mít InArgument<T> stejný typ členů kolekce, jako ForEach<T> je výčet.
Použití ActivityAction
Několik aktivit rozhraní .NET Framework 4.6.1 používá akce aktivity, jako Catch je aktivita a ForEach<T> aktivita. V každém případě akce aktivity představuje umístění, kde autor pracovního postupu určuje aktivitu, která zajistí požadované chování při vytváření pracovního postupu pomocí jedné z těchto aktivit. V následujícím příkladu ForEach<T> se aktivita používá k zobrazení textu v okně konzoly. ForEach<T> Tělo je určeno pomocí tohoActivityAction<T>, který odpovídá typuForEach<T>, který je řetězec. Aktivita WriteLine zadaná v argumentu Handler má Text svázanou s řetězcovými hodnotami v kolekci, kterou ForEach<T> aktivita iteruje.
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);
ActionArgument slouží k toku jednotlivých položek v kolekci do WriteLine. Při vyvolání pracovního postupu se v konzole zobrazí následující výstup.
HelloWorld.
Příklady v tomto tématu používají syntaxi inicializace objektů. Syntaxe inicializace objektů může být užitečný způsob, jak vytvořit definice pracovního postupu v kódu, protože poskytuje hierarchické zobrazení aktivit v pracovním postupu a zobrazuje vztah mezi aktivitami. Při programovém vytváření pracovních postupů není nutné používat syntaxi inicializace objektů. Následující příklad je funkčně ekvivalentní předchozímu příkladu.
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);
Další informace o inicializátorech objektů naleznete v tématu Postupy: Inicializace objektů bez volání konstruktoru (Průvodce programováním v C#) a Postupy: Deklarace objektu pomocí inicializátoru objektů (Visual Basic).
V následujícím příkladu TryCatch se aktivita používá v pracovním postupu. Pracovní postup vyvolá výjimku ApplicationException a zpracovává se aktivitou Catch<TException> . Obslužná rutina Catch<TException> akce aktivity aktivity je WriteLine aktivita a podrobnosti o výjimce se do ní protéká pomocí 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."
}
};
Při vytváření vlastní aktivity, která definuje ActivityAction<T>, použijte InvokeAction<T> k modelování vyvolání této ActivityAction<T>. V tomto příkladu je definována vlastní WriteLineWithNotification aktivita. Tato aktivita se skládá z Sequence aktivity, WriteLine za kterou následuje InvokeAction<T> aktivita, která vyvolá ActivityAction<T> jeden řetězcový argument.
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))
}
}
};
}
}
Když je pracovní postup vytvořen pomocí WriteLineWithNotification aktivity, autor pracovního postupu určuje požadovanou vlastní logiku v akci Handleraktivity . V tomto příkladu je vytvořen pracovní postup, který používá WriteLineWithNotification aktivitu a WriteLine aktivita se používá jako 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.
Existuje několik obecných verzí InvokeAction<T> a ActivityAction<T> poskytuje se pro předávání jednoho nebo více argumentů.
Použití activityFunc
ActivityAction<T> je užitečná v případě, že aktivita neobsahuje žádnou výslednou hodnotu a ActivityFunc<TResult> používá se, když se vrátí výsledná hodnota. Při vytváření vlastní aktivity, která definuje ActivityFunc<TResult>, použijte InvokeFunc<TResult> k modelování vyvolání této ActivityFunc<TResult>. V následujícím příkladu je definována WriteFillerText aktivita. Chcete-li zadat výplň textu, je zadána InvokeFunc<TResult> hodnota, která přebírá celočíselný argument a má výsledek řetězce. Jakmile se text výplně načte, zobrazí se v konzole pomocí WriteLine aktivity.
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)
}
}
};
}
}
Chcete-li zadat text, musí být použita aktivita, která přebírá jeden int argument a má výsledek řetězce. Tento příklad ukazuje TextGenerator aktivitu, která splňuje tyto požadavky.
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();
}
}
Chcete-li aktivitu s aktivitou TextGeneratorWriteFillerText použít, zadejte ji jako Handlerhodnotu .
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);