Propiedades de ejecución del flujo de trabajo
A través del almacenamiento local para el subproceso (TLS), el CLR mantiene un contexto de ejecución para cada subproceso. Este contexto de ejecución rige propiedades de subproceso bien conocidas, como la identidad del subproceso, la transacción ambiente y el conjunto de permisos actual así como las propiedades de subproceso definidas por el usuario como ranuras con nombre.
A diferencia de los programas que tienen por objetivo directo el CLR, los programas de flujo de trabajo son árboles con ámbito jerárquico de actividades que se ejecutan en un entorno independiente del subproceso. Esto implica que los mecanismos de TLS estándar no se pueden usar directamente para determinar qué contexto está en ámbito de un elemento de trabajo determinado. Por ejemplo, dos bifurcaciones paralelas de ejecución podrían usar distintas transacciones, aunque es posible que el programador intercale su ejecución en el mismo subproceso de CLR.
Las propiedades de ejecución del flujo de trabajo proporcionan un mecanismo para agregar propiedades específicas del contexto al entorno de una actividad. De esta forma se permite que una actividad declare qué propiedades están en ámbito para su subárbol y se proporcionen enlaces para configurar y destruir el TLS para interoperar correctamente con objetos CLR.
Crear y usar propiedades de ejecución de flujo de trabajo
Las propiedades de ejecución de flujo de trabajo implementan generalmente la interfaz IExecutionProperty , aunque las propiedades centradas en mensajería pueden implementar ISendMessageCallback y IReceiveMessageCallback en su lugar. Para crear una propiedad de ejecución de flujo de trabajo, cree una clase que implemente la interfaz IExecutionProperty e implemente los miembros SetupWorkflowThread y CleanupWorkflowThread. Estos miembros le dan a la propiedad de ejecución la oportunidad de configurar y anular el almacenamiento local de subprocesos durante cada pulso de trabajo de la actividad que contiene la propiedad, incluidas las actividades secundarias. En este ejemplo, se crea ConsoleColorProperty
, que establece 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;
}
}
Los autores de actividad pueden usar esta propiedad registrándola en el reemplazo de ejecución de la actividad. En este ejemplo, se define una actividad ConsoleColorScope
que registra ConsoleColorProperty
al agregarla a la colección de Properties de la clase NativeActivityContext actual.
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);
}
}
}
Cuando el cuerpo de la actividad comienza un pulso de trabajo, se llama al método SetupWorkflowThread de la propiedad y cuando el pulso de trabajo ha finalizado, se llama a CleanupWorkflowThread. En este ejemplo, se crea un flujo de trabajo que usa una actividad Parallel con tres bifurcaciones. Las primeras dos usan la actividad ConsoleColorScope
mientras que la tercera no. Las tres bifurcaciones incluyen dos actividades WriteLine y una actividad Delay. Cuando la actividad Parallel se ejecuta, las actividades contenidas en las bifurcaciones se ejecutan de modo intercalado, aunque cuando cada actividad secundaria se ejecuta, ConsoleColorProperty
aplica el color de la consola correcto.
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);
Cuando se invoca el flujo de trabajo, se escribe la siguiente salida en la ventana de la consola.
Start blue text.
Start red text.
Start default text.
End blue text.
End red text.
End default text.
Nota
Aunque no se muestra en la salida anterior, cada línea de texto en la ventana de la consola se muestra en el color indicado.
Los autores de actividad personalizados pueden usar las propiedades de ejecución del flujo de trabajo y también proporcionan el mecanismo para controlar la administración de las actividades como CorrelationScope y TransactionScope.