在 Windows Workflow Foundation (WF)中,变量表示数据的存储,参数表示传入和传出活动的数据流。 活动拥有一组自变量,这些自变量构成活动的签名。 此外,活动还可以维护开发人员可以在工作流设计期间添加或删除变量的变量列表。 参数使用返回值的表达式进行绑定。
变量
变量是数据的存储位置。 变量声明为工作流定义的一部分。 变量在运行时接受值,这些值作为工作流实例状态的一部分存储。 变量定义指定变量的类型,并根据需要指定名称。 以下代码演示如何声明变量、使用 Assign<T> 活动为其赋值,然后使用活动将其值显示给控制台 WriteLine 。
// Define a variable named "str" of type string.
Variable<string> var = new Variable<string>
{
Name = "str"
};
// Declare the variable within a Sequence, assign
// a value to it, and then display it.
Activity wf = new Sequence()
{
Variables = { var },
Activities =
{
new Assign<string>
{
To = var,
Value = "Hello World."
},
new WriteLine
{
Text = var
}
}
};
WorkflowInvoker.Invoke(wf);
可以选择将默认值表达式指定为变量声明的一部分。 变量还可以具有修饰符。 例如,如果变量为只读,则可以应用只读 VariableModifiers 修饰符。 在以下示例中,将创建一个具有分配默认值的只读变量。
// Define a read-only variable with a default value.
Variable<string> var = new Variable<string>
{
Default = "Hello World.",
Modifiers = VariableModifiers.ReadOnly
};
变量的作用域
运行时变量的生存期等于声明它的活动的生存期。 活动完成后,将清理其变量,并且无法再引用。
论据
活动作者使用参数来定义数据流入和流出活动的方式。 每个参数都有一个指定的方向: In, Out或 InOut。
工作流运行时对数据流入流出活动的时间有以下保证:
当活动开始执行时,将计算其所有输入和输出参数的值。 例如,无论 Get 何时调用,返回的值都是运行时在调用
Execute
之前计算的值。调用时 Set ,运行时会立即设置值。
参数可以选择性地指定 EvaluationOrder。 EvaluationOrder 是一个从零开始的值,该值指定参数的计算顺序。 默认情况下,参数的求值顺序未指定且等于 UnspecifiedEvaluationOrder 值。 设置为 EvaluationOrder 大于或等于零的值,以指定此参数的计算顺序。 Windows Workflow Foundation 按指定的计算顺序以升序评估参数。 请注意,具有未指定计算顺序的参数在具有指定求值顺序的参数之前进行求值。
活动作者可使用强类型机制来公开该活动的参数。 这是通过声明类型InArgument<T>、OutArgument<T>和InOutArgument<T>的属性来实现的。 这样,活动作者就可以建立有关传入和传出活动的数据的特定协定。
定义活动的自变量
可以在活动中通过指定类型InArgument<T>、OutArgument<T>和InOutArgument<T>的属性来定义参数。 以下代码演示如何定义一个 Prompt
活动的参数,该活动接受字符串以显示给用户,并返回一个包含用户响应的字符串。
public class Prompt : Activity
{
public InArgument<string> Text { get; set; }
public OutArgument<string> Response { get; set; }
// Rest of activity definition omitted.
}
注释
返回单个值的活动可以派生自Activity<TResult>、NativeActivity<TResult>或CodeActivity<TResult>。 这些活动拥有定义完善的名为 OutArgument<T> 的 Result,它包含活动的返回值。
在工作流中使用变量和参数
以下示例演示如何在工作流中使用变量和参数。 工作流是一个声明三个变量的序列: var1
、 var2
和 var3
。 工作流中的第一个活动是一个Assign
活动,它将变量var1
的值分配给变量var2
。 接下来是 WriteLine
活动,该活动打印 var2
变量的值。 接下来是另一个活动,将变量 Assign
的值分配给变量 var2
。 最后是另一个 WriteLine
活动,该活动打印 var3
变量的值。 第一个 Assign
活动使用 InArgument<string>
和 OutArgument<string>
对象显式表示活动参数的绑定。
InArgument<string>
用于Value,因为值正通过其Assign<T>参数流入Value活动,而OutArgument<string>
用于To,因为该值正从To参数流出到变量中。 第二个 Assign
活动完成相同的操作,它采用更加紧凑的语法,通过使用隐式强制转换而达到相同目的。
WriteLine
活动也使用紧凑语法。
// Declare three variables; the first one is given an initial value.
Variable<string> var1 = new Variable<string>()
{
Default = "one"
};
Variable<string> var2 = new Variable<string>();
Variable<string> var3 = new Variable<string>();
// Define the workflow
Activity wf = new Sequence
{
Variables = { var1, var2, var3 },
Activities =
{
new Assign<string>()
{
Value = new InArgument<string>(var1),
To = new OutArgument<string>(var2)
},
new WriteLine() { Text = var2 },
new Assign<string>()
{
Value = var2,
To = var3
},
new WriteLine() { Text = var3 }
}
};
WorkflowInvoker.Invoke(wf);
在 Code-Based 活动中使用变量和参数
前面的示例演示如何在工作流和声明性活动中使用参数和变量。 参数和变量也用于基于代码的活动。 从概念上讲,用法非常相似。 变量表示活动内的数据存储,参数表示传入或传出活动的数据流,并由工作流作者绑定到工作流中的其他变量或参数,这些变量或参数表示数据流向或流出的位置。 若要获取或设置活动中变量或参数的值,必须使用活动上下文来表示活动的当前执行环境。 工作流运行时将其传递到活动的 Execute 方法中。 在此示例中,定义了一个具有两Add
个参数的自定义In活动。 为了访问这些自变量的值,使用了 Get 方法,并使用了由工作流运行时传入的上下文。
public sealed class Add : CodeActivity<int>
{
[RequiredArgument]
public InArgument<int> Operand1 { get; set; }
[RequiredArgument]
public InArgument<int> Operand2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
return Operand1.Get(context) + Operand2.Get(context);
}
}