🐋作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
🐬个人主页:会敲键盘的肘子
🐰系列专栏:.Net实用方法总结
🦀专栏简介:本专栏介绍如何编写 Windows Workflow Foundation (WWF) 应用程序。 WWF是RPA开发的前置知识。按照本专栏的过程操作,将生成一个猜数游戏应用程序。 本教程中的第一个主题将逐步引导您创建工作流所需的自定义Activity。 在第二个主题中,将这些Activity与内置的工作流Activity组合成一个Flowchart。 在第三个主题中,配置主机应用程序以运行工作流,并在最后的主题中介绍持久性。
🌈写在前面:
Activity是 WWF 中的核心行为单元。 Activity的执行逻辑可以使用托管代码实现,也可以使用其他Activity实现。 本文介绍System.Activities.Statements命名空间**ForEach**类。
👉本文关键字:RPA、WWF、Activity、ForEach类
文章目录
- 1️⃣ 概述
- ♈ 工作流运行时引擎
- 2️⃣ ForEach<T>类
- ♈ 定义
- ♉ 构造函数
- ForEach<T>()
- ♊ 属性
- Body
- CacheId
- Constraints
- DisplayName
- Id
- Variables
- ♌ 方法
- Execute(CodeActivityContext)
- ShouldSerializeDisplayName()
1️⃣ 概述
工作流是一组存储为模型的名为活动的基本单元,该模型用于描述实际进程。 工作流提供了一种方法,用于描述多项短期运行或长期运行的工作之间的执行顺序和依赖关系。 此工作从头到尾地贯穿模型,并且活动可以人工执行或由系统功能执行。
♈ 工作流运行时引擎
每个正在运行的工作流实例都是由进程内运行时引擎创建和维护的,托管进程通过以下类之一与其交互:
- WorkflowInvoker,它像调用方法一样调用工作流。
- WorkflowApplication,用于对单个工作流实例的执行进行显式控制。
- WorkflowServiceHost,用于多实例方案中基于消息的交互。
上述每个类对表示为负责活动执行的 ActivityInstance 的核心活动运行时进行包装。 在一个应用程序域中可以并发运行多个 ActivityInstance 对象。
上述三个主机交互对象中的每一个都是从称为工作流程序的活动树中创建的。 使用这些类型或对 ActivityInstance 进行包装的自定义宿主,可以在包括控制台应用程序、基于窗体的应用程序、Windows 服务、ASP.NET Web 网站和 Windows Communication Foundation (WCF) 服务在内的任何 Windows 进程内执行工作流。
在上图中,Invoke 类的 WorkflowInvoker 方法用于调用多个工作流实例。 WorkflowInvoker 用于不需要由宿主管理的轻型工作流;需要由宿主管理的工作流(如 Bookmark 恢复)必须改用 Run 来执行。 无需等待一个工作流实例完成即可调用下一个工作流实例;运行时引擎支持同时运行多个工作流实例。 调用的工作流如下:
- 一个包含 Sequence 子活动的 WriteLine 活动。 父活动的 Variable 绑定到子活动的 InArgument。 有关变量、参数和绑定的详细信息,请参阅变量和参数。
- 一个调用
ReadLine
的自定义活动。 将 OutArgument 活动的ReadLine
返回给调用 Invoke 方法。 - 一个派生自 CodeActivity 抽象类的自定义活动。 CodeActivity 可以使用作为 CodeActivityContext 方法的参数提供的 Execute 访问运行时功能(如跟踪和属性)。 有关这些运行时功能的详细信息,请参阅工作流跟踪和工作流执行属性。
2️⃣ ForEach类
♈ 定义
为 Values 集合中提供的每个值执行活动操作一次。
[System.Windows.Markup.ContentProperty("Body")]
public sealed class ForEach<T> : System.Activities.NativeActivity
类型参数
T
Values 集合中提供的值的类型。
♉ 构造函数
ForEach()
创建 ForEach 类的新实例。
public ForEach ();
示例
下面的代码示例演示如何创建 ForEach 活动。 此示例摘自 DynamicActivity 创建 示例。
new ForEach<int>
{
Values = new ArgumentValue<IEnumerable<int>> { ArgumentName = "Numbers" },
Body = new ActivityAction<int>
{
Argument = iterationVariable,
Handler = new Assign<int>
{
To = accumulator,
Value = new InArgument<int>(env => iterationVariable.Get(env) + accumulator.Get(env))
}
}
},
ForEach 类似于 关键字
foreach
,但实现为活动而不是语言语句。 请注意,与 C# 不同foreach
,活动使用 GetEnumerator,而不是 IEnumeratorForEach 。
♊ 属性
Body
要在每次迭代中执行的子活动。
[System.Windows.Markup.DependsOn("Condition")]
public System.Activities.Activity Body { get; set; }
CacheId
获取缓存的标识符,该标识符在工作流定义的作用域内是唯一的。
protected internal int CacheId { get; }
Constraints
获取可配置的 Constraint 活动的集合,用于为 Activity 提供验证。
protected System.Collections.ObjectModel.Collection<System.Activities.Validation.Constraint> Constraints { get; }
DisplayName
获取或设置用于调试、验证、异常处理和跟踪的可选友好名称。
public string DisplayName { get; set; }
Id
获取一个标识符,该标识符在工作流定义的作用域内是唯一的。
public string Id { get; }
Variables
与 Variable 活动关联的 DoWhile 对象的集合。
public System.Collections.ObjectModel.Collection<System.Activities.Variable> Variables { get; }
♌ 方法
Execute(CodeActivityContext)
在派生类中实现时,执行该活动。
protected abstract void Execute (System.Activities.CodeActivityContext context);
参数
context
CodeActivityContext
执行活动时所处的执行上下文。
ShouldSerializeDisplayName()
指示是否应序列化 DisplayName 属性。
public bool ShouldSerializeDisplayName ();
返回
Boolean
如果应当将 DisplayName 属性值序列化,则为
true
;否则为false
。
⭐写在结尾:
文章中出现的任何错误请大家批评指出,一定及时修改。
希望写在这里的小伙伴能给个三连支持!