Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Delegados de atividade permitem que autores de atividades exponham retornos de chamada com assinaturas específicas, para que os usuários da atividade possam fornecer manipuladores com base na atividade. Dois tipos de representantes de atividade estão disponíveis: ActivityAction<T> é usado para definir os representantes de atividade que não têm um valor de retorno, e ActivityFunc<TResult> é usado para definir os representantes de atividade que têm um valor de retorno.
Os representantes de atividade são úteis em situações onde uma atividade filho deve ser restrita a ter uma determinada assinatura. Por exemplo, uma atividade de While pode conter qualquer tipo de atividade filha sem restrições, mas o corpo de uma atividade de ForEach<T> é ActivityAction<T>, e a atividade filha que é finalmente executada por ForEach<T> deve ter um InArgument<T> do mesmo tipo dos membros da coleção que ForEach<T> enumera.
Usando ActivityAction
Várias atividades do .NET Framework 4.6.1 usam ações de atividade, como a atividade de Catch e a atividade de ForEach<T>. Em cada caso, a ação de atividade representa um local onde o autor de fluxo de trabalho especifica uma atividade para fornecer um comportamento desejado quando estiver compondo um fluxo de trabalho usando uma dessas atividades. No exemplo a seguir, uma atividade de ForEach<T> é usada para exibir texto na janela do console. O corpo de ForEach<T> é especificado usando ActivityAction<T> que corresponde ao tipo de ForEach<T> que é cadeia de caracteres. A atividade WriteLine especificada em Handler tem seu argumento Text vinculado aos valores de cadeia de caracteres na coleção que a atividade ForEach<T> itera.
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);
O actionArgument é usado para encaminhar os itens individuais na coleção para WriteLine. Quando o fluxo de trabalho é chamado, a saída a seguir é exibida no console.
HelloWorld.
Os exemplos deste tópico usam sintaxe de inicialização de objeto. A sintaxe de inicialização de objeto pode ser uma maneira útil de criar definições de fluxo de trabalho no código porque fornece uma exibição hierárquica das atividades no fluxo de trabalho e mostra a relação entre as atividades. Não há nenhum requisito para usar a sintaxe de inicialização de objeto quando você cria fluxos de trabalho programaticamente. O exemplo a seguir é funcionalmente equivalente ao exemplo anterior.
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);
Para obter mais informações sobre os inicializadores do objeto, consulte Como inicializar objetos sem chamar um construtor (Guia de programação em C#) e Como declarar um objeto usando um inicializador de objeto (Visual Basic).
No exemplo a seguir, uma TryCatch atividade é usada em um fluxo de trabalho. Um ApplicationException é lançado pelo fluxo de trabalho e é tratado por uma atividade de Catch<TException>. O manipulador para a ação da atividade Catch<TException> é uma atividade WriteLine, e o detalhe de exceção é transmitido para ela utilizando 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."
}
};
Ao criar uma atividade personalizada que define ActivityAction<T>, use um InvokeAction<T> para modelar a invocação do ActivityAction<T>. Nesse exemplo, uma atividade personalizada de WriteLineWithNotification é definida. Esta atividade é composta de Sequence que contém uma atividade de WriteLine seguida por InvokeAction<T> que invoca ActivityAction<T> que recebe um argumento do tipo string.
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))
}
}
};
}
}
Quando um fluxo de trabalho é criado usando a atividade WriteLineWithNotification, o autor do fluxo de trabalho especifica a lógica personalizada desejada na ação da atividade Handler. Nesse exemplo, um fluxo de trabalho é criado usando a atividade de WriteLineWithNotification , e uma atividade de WriteLine é usada como 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.
Há várias versões genéricas de InvokeAction<T> e de ActivityAction<T> fornecidas para passar um ou mais argumentos.
Usando ActivityFunc
ActivityAction<T> é útil quando não há nenhum valor do resultado da atividade, e ActivityFunc<TResult> é usado quando um valor de resultado é retornado. Ao criar uma atividade personalizada que define ActivityFunc<TResult>, use um InvokeFunc<TResult> para modelar a invocação do ActivityFunc<TResult>. No exemplo a seguir, uma atividade de WriteFillerText é definida. Para fornecer o texto preenchido, especifica-se um InvokeFunc<TResult> que recebe um argumento inteiro e apresenta um resultado string. Uma vez que o texto de preenchimento é recuperado, ele é exibido no console usando uma atividade de WriteLine.
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)
}
}
};
}
}
Para fornecer texto, uma atividade deve ser usada que recebe um argumento de int e tem um resultado de cadeia de caracteres. Este exemplo mostra uma atividade de TextGenerator que atenda a esses requisitos.
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();
}
}
Para usar a atividade de TextGenerator com a atividade de WriteFillerText , especifique-o como 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);