Propriedades de execução do fluxo de trabalho
Através do armazenamento local de thread (TLS), o CLR mantém um contexto de execução para cada thread. Esse contexto de execução rege propriedades de thread bem conhecidas, como a identidade do thread, a transação de ambiente e o conjunto de permissões atual, além das propriedades de thread definidas pelo usuário, como slots nomeados.
Ao contrário dos programas direcionados diretamente ao CLR, os programas de fluxo de trabalho são árvores de escopo hierárquico de atividades que são executadas em um ambiente independente de threads. Isso implica que os mecanismos TLS padrão não podem ser usados diretamente para determinar qual contexto está no escopo de um determinado item de trabalho. Por exemplo, duas ramificações paralelas de execução podem usar transações diferentes, mas o agendador pode intercalar sua execução no mesmo thread CLR.
As propriedades de execução do fluxo de trabalho fornecem um mecanismo para adicionar propriedades específicas do contexto ao ambiente de uma atividade. Isso permite que uma atividade declare quais propriedades estão no escopo de sua subárvore e também fornece ganchos para configurar e derrubar TLS para interoperar adequadamente com objetos CLR.
Criando e usando propriedades de execução de fluxo de trabalho
As propriedades de execução do fluxo de trabalho geralmente implementam a interface, embora as IExecutionProperty propriedades focadas em mensagens possam ser implementadas ISendMessageCallbackIReceiveMessageCallback . Para criar uma propriedade de execução de fluxo de trabalho, crie uma classe que implemente a IExecutionProperty interface e implemente os membros SetupWorkflowThread e CleanupWorkflowThread. Esses membros fornecem à propriedade de execução uma oportunidade de configurar e derrubar corretamente o armazenamento local de thread durante cada pulso de trabalho da atividade que contém a propriedade, incluindo quaisquer atividades filhas. Neste exemplo, é criado um ConsoleColorProperty
que define o Console.ForegroundColor
.
class ConsoleColorProperty : IExecutionProperty
{
public const string Name = "ConsoleColorProperty";
ConsoleColor original;
ConsoleColor color;
public ConsoleColorProperty(ConsoleColor color)
{
this.color = color;
}
void IExecutionProperty.SetupWorkflowThread()
{
original = Console.ForegroundColor;
Console.ForegroundColor = color;
}
void IExecutionProperty.CleanupWorkflowThread()
{
Console.ForegroundColor = original;
}
}
Os autores de atividade podem usar essa propriedade registrando-a na substituição de execução da atividade. Neste exemplo, é definida uma ConsoleColorScope
atividade que registra o adicionando-o ConsoleColorProperty
Properties à coleção do atual NativeActivityContext.
public sealed class ConsoleColorScope : NativeActivity
{
public ConsoleColorScope()
: base()
{
}
public ConsoleColor Color { get; set; }
public Activity Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
context.Properties.Add(ConsoleColorProperty.Name, new ConsoleColorProperty(this.Color));
if (this.Body != null)
{
context.ScheduleActivity(this.Body);
}
}
}
Quando o corpo da atividade inicia um pulso de trabalho, o SetupWorkflowThread método da propriedade é chamado, e quando o pulso do trabalho é concluído, o CleanupWorkflowThread é chamado. Neste exemplo, é criado um fluxo de trabalho que usa uma Parallel atividade com três ramificações. Os dois primeiros ramos utilizam a ConsoleColorScope
atividade e o terceiro não. Os três ramos contêm duas WriteLine atividades e uma Delay atividade. Quando a Parallel atividade é executada, as atividades contidas nas ramificações são executadas de maneira intercalada, mas à medida que cada atividade filho é executada, a cor correta do console é aplicada pelo ConsoleColorProperty
.
Activity wf = new Parallel
{
Branches =
{
new ConsoleColorScope
{
Color = ConsoleColor.Blue,
Body = new Sequence
{
Activities =
{
new WriteLine
{
Text = "Start blue text."
},
new Delay
{
Duration = TimeSpan.FromSeconds(1)
},
new WriteLine
{
Text = "End blue text."
}
}
}
},
new ConsoleColorScope
{
Color = ConsoleColor.Red,
Body = new Sequence
{
Activities =
{
new WriteLine
{
Text = "Start red text."
},
new Delay
{
Duration = TimeSpan.FromSeconds(1)
},
new WriteLine
{
Text = "End red text."
}
}
}
},
new Sequence
{
Activities =
{
new WriteLine
{
Text = "Start default text."
},
new Delay
{
Duration = TimeSpan.FromSeconds(1)
},
new WriteLine
{
Text = "End default text."
}
}
}
}
};
WorkflowInvoker.Invoke(wf);
Quando o fluxo de trabalho é invocado, a saída a seguir é gravada na janela do console.
Start blue text.
Start red text.
Start default text.
End blue text.
End red text.
End default text.
Nota
Embora não seja mostrado na saída anterior, cada linha de texto na janela do console é exibida na cor indicada.
As propriedades de execução do fluxo de trabalho podem ser usadas por autores de atividades personalizadas e também fornecem o mecanismo para manipular o gerenciamento de atividades como as CorrelationScopeTransactionScope e atividades.