通过线程本地存储(TLS),CLR 为每个线程维护执行上下文。 除了用户定义的线程属性(如命名槽)之外,此执行上下文还控制已知线程属性,例如线程标识、环境事务和当前权限集。
与直接面向 CLR 的程序不同,工作流程序是跨层次范围的活动树,这些树在与线程无关的环境中执行。 这意味着标准 TLS 机制不能直接用于确定给定工作项的范围中的上下文。 例如,两个并行执行的分支可能会使用不同的事务,而计时程序可能会将它们的执行交错在同一 CLR 线程上。
工作流执行属性提供一种机制,用于向活动环境添加特定于上下文的属性。 这将允许活动声明哪些属性在其子树范围内,并且还提供了用于设置和关闭 TLS 以与 CLR 对象正确交互的挂钩。
创建和使用工作流执行属性
工作流执行属性通常实现IExecutionProperty接口,但侧重于消息传送的属性可能实现ISendMessageCallback和IReceiveMessageCallback。 要创建工作流执行属性,请创建一个实现接口 IExecutionProperty 的类,并且实现成员 SetupWorkflowThread 和 CleanupWorkflowThread。 这些成员为执行特性提供了一个机会,让它能够在包含该特性的活动的每个工作周期(包括任何子活动)期间,正确地配置和销毁线程本地存储。 在本示例中,创建了设置 ConsoleColorProperty
的 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;
}
}
活动创作者可通过在该活动的执行重写中注册此属性来使用它。 在此示例中,定义一个ConsoleColorScope
活动,该活动通过将ConsoleColorProperty
添加到当前Properties的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);
}
}
}
当活动开始工作周期时,将调用属性的SetupWorkflowThread方法,当工作周期完成时,将调用CleanupWorkflowThread方法。 在此示例中,将创建一个工作流,该工作流使用具有三个 Parallel 分支的活动。 前两个分支使用 ConsoleColorScope
活动,第三个分支不使用。 所有三个分支都包含两个WriteLine活动和一个Delay活动。
Parallel执行活动时,分支中包含的活动会交替执行,而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);
调用工作流时,以下输出将写入控制台窗口。
Start blue text.
Start red text.
Start default text.
End blue text.
End red text.
End default text.
注释
虽然上一个输出中未显示它,但控制台窗口中的每行文本都以指示的颜色显示。
工作流执行属性可由自定义活动作者使用,它们还提供用于处理活动(如 CorrelationScope 和活动 TransactionScope )的管理的机制。