【Asp.net精品源码栏目提醒】:网学会员鉴于大家对Asp.net精品源码十分关注,论文会员在此为大家搜集整理了“【精品】WF从入门到精通(中文版) - 其它资料”一文,供大家参考学习
第一章 【翻译】WF 从入门到精通(第一章):WF 简介 学习完本章,你将掌握: 1.了解工作流的概念和理论 2.把 WF 和 BizTalk 与 WCF 做比较 3.开始使用 WF 进行编程 4.知道怎样使用 Visual Studio 工作流支持 以下是一小段进行邮政编码验证的代码 string USCode quotd5d5-d4quot string CanadianCode quotABCEGHJKLMNPRSTVXYDA-ZdA-Zdquot public static bool ValidatePostalCodestring str return Regex.IsMatchstrUSCodeRegex.IsMatchstrCanadianCode 这没有什么特别的:“测试一个输入的字符串,如果为美国 ZIP 编码或者加拿大邮政编码则返回 True,否则返回 False”。
这是一段很实用的代 码,事实上假如你不想在
ASP.NET中使用其它验证控件的话你就可在你的
ASP.NET 中使用这段验证逻辑。
我们现在就创建一个Workflow 应用 程序,它将进行同样的验证,并且返回验证是否通过的信息。
创建一个基于控制台的 Workflow 项目 1.启动 Visual Studio 2008 2.创建顺序工作流控制台应用程序项目 3.项目名称中输入 PCodeFlow 4.点击确定,将自动生成下面的初始界面 在编辑代码或插入 Workflow 项前,停留片刻看看 Workflow 项目为你生成的两个文件: Program.cs:从许多方面可以看出这是一个典型的控制台应用程序源文件。
然而,这个模板增加了大量代码来支持 Workflow 的操作。
理解这些代码是本书的一个主要目标,但本章只是简单了解一下它做了些什么。
Workflow1.cs:这是一个 Workflow 组件,我们将对其进行修改以进行邮政编码的验证,第一次使用你就可以放入许多东西,但我们现在还是从使用这个简单的 Workflow 开始工作吧。
创建一个工作流 在工具箱中拖一个 IfElse 活动组件到 workflow 设计界面上。
我们现在将使用 IfElse 活动组件来问下面的问题:“我们已有的一个字符串是一个合法的邮政编码吗”。
我们在代码中将确实使用先前你看到的代码段中的正则表达式来问这一问题。
但 在我们进行这一步前请仔细看看 workflow 的视图设计器。
workflow 视图设计器提醒我们没有提供相应的代码来做这一决定。
假如你看看命名为 “ifElseBranchActivity1”的左边分支的右上角,你将看到里面有一个惊叹号标记的小圆形图标。
这是 workflow 视图设计器在告诉 你 workflow 并不完整。
假如你试图编译带有这种提醒图标的项目时,将会编译报错。
如你把鼠标移到图标上并单击呈现出的向下箭头时,你还能看到更多关 于这一错误情况的信息。
在 IfElse 活动的分支上添加代码 1.移动鼠标到命名为“ifElseBranchActivity1”的左边分支上, 单击以在属性面板上激活这一分支的属性。
2. 我们添加一个条件,意思是说 workflow 执行到分支时将强制其执行一些动作(条件判断为 True 时,将执行左边分支)。
为做到这些,单击 “condition”属性激活条件类型属性的下拉列表。
从列表中你可以选择“代码条件”类型、“(无)”类型和“声明性规则条件”类型。
这里选择“代码 条件”类型。
3.上述步骤完成后,“condition”类型属性用户界面会包含一个“”号,我们单击展开它的子属性,该子属性也命名为“condition”,单击以激活它。
4.“condition”属性需要输入我们想添加的内部事件名字。
当条件需要判断时这个事件将激发。
在本例子中我们输入“EvaluatePostalCode”。
Visual studio 2008 在幕后为你在 workflow 源文件中添加了你在“condition”属性中所指明的事件。
稍候我们将添加在事件激发时所要执行的正则表达式代码段。
在我们做这些工作之前,让我们继续在 workflow 视图设计器上工作,我们刚刚增加了一个条件,它将引发工作流选择左边路径还是右边路 径。
但是两条路径中都没有指明工作流将进行的动作。
我们在左边“ifElseBranchActivity1”分支和右边“ifElseBranchActivity2”分支中添加活动。
添加 Code 活动 1.拖一个“Code”活动到 workflow 视图设计器上,并放到左边分支(ifElseBranchActivity1)的区域内。
2.就像先前添加条件判断的代码一样,我们将为该分支添加被选中时执行的代码。
单击“codeActivity1”图标以在属性面板中激活它的属性。
3.在“ExecuteCode”属性中输入“PostalCodeValid”。
Visual Studio 2008 会自动插入该事件。
稍候我们会提供对应的执行代码。
右边分支也同样做,只是要在“ExecuteCode”属性中输入“PostalCodeInValid”。
在我们的 workflow 中添加事件处理代码 1.打开 Workflow.cs 准备进行编辑 2.添加引用:using System.Text.RegularExpression 3.定位到“EvaluatePostalCode”方法上,插入下面的代码: private void EvaluatePostalCodeobject sender ConditionalEventArgs e string USCode quotd5d5-d4quot string CanadianCode quotABCEGHJKLMNPRSTVXYDA-ZdA-Zdquot e.Result Regex.IsMatch_code USCode Regex.IsMatch_code CanadianCode 变量 e 是“ConditionalEventArgs”类型的实例,它用来告知“IfElse”活动应选择哪条路径。
4.我们也需要为 workflow 活动添加一种能力,以便接受输入的字符串来进行验证工作。
为此我们添加下面的代码,我们将声明一个名为“PostalCode”的公有属性。
private string _codestring.Empty public string PostalCode get return _code set _code value 有了这些,我们的 workflow 应用程序就可以进行编译了,但程序并不完整,我们还要在Workflow1.cs 文件中定位到“PostalCodeValid”方法并插入下面的代码: Console.WritequotThe postal code 0 is valid.quot _code 同样在“PostalCodeInValid”方法中插入下面的代码: Console.WritequotThe postal code 0 is invalid.quot _code 调用工作流 1.打开 Program.cs 文件。
2.定位到: WorkflowInstance instance workflowRuntime.CreateWorkflowtypeofPCodeFlow.Workflow1wfArgs 3.把上述代码替换为: Dictionaryltstring objectgt wfArgs new Dictionaryltstring objectgt wfArgs.AddquotPostalCodequot args.Length gt 0 args0 : quotquotWorkflowInstance instance workflowRuntime.CreateWorkflowtypeofPCodeFlow.Workflow1wfArgs 编译应用程序 执行你的工作流应用程序 1.打开命令提示符窗口。
2.在命令提示符下定位到编译后所生成的应用程序目录。
3.输入 pcodeflow 12345 查看执行结果。
4.输入 pcodeflow 1234x 再看看执行结果。
源码下载 http://files.cnblogs.com/gyche/PCodeFlow.rar 第二章 【翻译】WF 从入门到精通(第二章):workflow 运行时 学习完本章后,你将掌握: 1.在你的应用程序中使用 workflow 2.理解“WorkflowRuntime”对象的的基本功能 3.知道如何启动和停止 workflow 运行时 4.能够使用各种 workflow 运行时的相关事件 当 你在 WF 环境中执行任务时,需要一些东西来监管执行的过程,这个东西就是命名为“WorkflowRuntime”的对象。
WorkflowRuntime 启动一个独立的工作流任务。
在你的任务执行过程中, 并 WorkflowRuntime 也会针对不同的情况响应对应的事件。
且, WorkflowRuntime还能在你的执行环境中增加一个附加的服务来保持跟踪。
WF 架构纵览见下图: WF 和你的应用程序并行执行。
其实,我们需要你的应用程序作为宿主。
宿主应用程序可以是 Windows Forms 应用程序,控制台应用程序,
ASP.NET WEB 应用程序,甚至可以是一个Windows Server。
WF 运行时和你的应用程序同在一个.NET 应用程序域执行,每个应用程序域只有一个唯一的 WorkflowRuntime 实例,试图在一个 应用程序域中建立第二个WorkflowRuntime 的实例的话,其结果就是抛出一个“InvalidOperationException”异常。
workflow 应用程序-“workflows”-意思指创建的逻辑上的一组活动。
这些逻辑上的活动用来完成你需要的工作流任务。
当你宿主 workflow 运行时的时 候,其实你就在操作工作流中的活动并让 workflow 运行时执行他们。
其结果就是生成一个 workflow 实例,workflow实例是一个当前正执行 的 workflow 任务,它能自己完成逻辑上的一组活动,回忆第一章吧,活动能执行你提供的代码并且能对输入的数据做出相应的决定。
下一章我们将简述工作 流实例,后面几章将对活动进行介绍。
在宿主应用程序中添加 WF 一、创建一个名称为 WorkflowHost 的控制台应用程序项目 二、为项目添加名为 System.Workflow.Runtime 的引用 三、宿主 workflow 运行时 1.打开 Program.cs 文件准备编辑 2.在“using System.Text”下添加以下代码: “using System.Workflow.Runtime” 3.定位到“Main”方法,在里面添加以下代码: WorkflowRuntime workflowRuntimenew WorkflowRuntime 4.编译程序确认没有错误。
在本章我们都将使用这一应用程序。
四、深入了解 WorkflowRuntime 对象 我们现在已经在我们的宿主应用程序中建立了一个 WorkflowRuntime 类型的实例,该是简单的了解怎样和这个对象交互的时候了。
和大多数有用的 对象一样,WorkflowRuntime 也暴露了一些方法和属性,我们可用他们来控制 Workflow 运行时的环境。
表 2-1 列出了所有WorkflowRuntime 属性,表 2-2 则列出了我们经常使用的方法。
表 2-1 WorkflowRuntime 的属性属性 功能 用来指明 workflow 运行时是否已经启动并准备接受 workflow 实例。
当宿主调用IsStarted “StartRuntime”前 IsStarted 为 False。
期间它一直维持 True 直到宿主调用 “StopRuntime”为止。
需注意的是当它正在运行中你不能增加核心服务。
获取或设置和 WorkflowRuntime 关联的名字。
Workflow 运行时正在运行中你不能Name 设置这个属性(也就是说当 IsStarted 为 True)。
企图这样做的结果就是抛出一 个“InvalidOperationException”异常。
表 2-2 WorkflowRuntime 的方法方法 功能 为 workflow 运行时添加指定的服务。
能添加的服务类型和时间受到种种限AddService 制。
关于服务的详细信息将在第五章介绍。
创建一个 workflow 实例,它包含一些指定(但可选)的参数。
假如 workflowCreateWorkflow 运行时没有启动,该方法就调用 StartRuntime 方法。
通过 指明 workflow 实例的标识符(由一个 Guid 组成)来检索 workflow 实GetWorkflow 例。
假如这个 workflow 实例是空闲和持久化保存的,它将被重新加载并执 行。
StartRuntime 启动 workflow 运行时和相关服务,并引发“Started”事件。
StopRuntime 停止 workflow 运行时和相关服务,并引发“Stoped”事件。
还有更多的关于 WorkflowRuntime 的方法, 但表 2-2 中列出的方法是最经常用到的方法,也是我们将重点关注的方法。
在 workflow 运行期间,WorkflowRuntime 也将在各种时间引发许多事件,但我们将在后面的章节中介绍。
创建一个 Workflow 运行时工厂 单 例和工厂设计模式的组合是强大的, 因为工厂能保证只创建出一个曾创建的对象的单一实例,这正好符合我们的要求(在这里使用单例模式的原因主要是从效率上考 虑,其次一个应用程序域也只能只有一个 WorkflowRuntime),因为 WorkflowRuntime 完全有可能在不同的应用当中加载和启动(例 如独立的应用模块)。
让我们看看怎样创建一个WorkflowRuntime 工厂。
一、在项目中添加一个类型为类的新项,文件名为 WorkflowFactory.cs。
二、在 WorkflowFactory.cs 源文件中添加如下的引用 using System.Workflow.Runtime 三、在类中添加下面的代码: //workflow runtime 的单一实例 private static WorkflowRuntime _workflowRuntime null private static object _syncRoot new object 四、在上述代码后添加如下方法: //工厂方法 public static WorkflowRuntime GetWorkflowRuntime //多线程环境下防止并发访问 lock _syncRoot if null _workflowRuntime _workflowRuntime new WorkflowRuntime return _workflowRuntime 五、为类加上 Public 关键字,为防止类被直接实例化,还必须为类加上 static 标记,如下所示: public static class workflowFactory 启动 workflow 运行时 参 考表 2-2,里面有一个 StartRuntime 方法,从我们的工厂对象中调用这个方法很有意义,外部对象要求 workflow 运行时对象无需处理或担心 运行时环境状态的初始化。
我们需要在我们的应用程序通过这一步来建立我们需要的 workflow 环境。
外部调用对象也需要workflow 运行时对象易于 使用。
并不是一定要调用 StartRuntime。
假如我们建立了一个 workflow 实例,StartRuntime实际上就已被调 用。
假如我们曾经创建了一个 workflow 实例,或许并不用担心需要明确的调用 StartRuntime。
但是,一旦我们添加服务时,明确地调用它就很 有必要,因为可增强代码的可维护性并确信运行时环境的状态已建立, 这样任何人就都能使用 workflow 运行时对象。
因此让我们在我们的工厂对象中做些轻微的更改并直接调用 StartRuntime。
1.打开 WorkflowFactory.cs 文件并定位到下面的代码上: _workflowRuntime new WorkflowRuntime 2.在上面的代码下添加以下的代码: _workflowRuntime.Starttime 停止 workflow 运行时 是 否有办法启动一个 workflow 运行时很有意义,如何停止一个 workflow 运行时也一样。
看看表 2-2 吧,里面有一个 StopRuntime 方法正 好符合我们要求。
调用 StopRuntime 方法会卸载所有正执行的 workflow 和服务并关闭 workflow 运行时环境。
当然,正确调用StopRuntime 位置是在你申请停止逻辑结束之前或者应用程序域关闭前调用。
1.打开 WorkflowFactory.cs 文件并定位到下面的代码上 _workflowRuntime new WorkflowRuntime 2.在上面代码的前面增加以下代码: _workflowRuntime.Starttime 3.在 WorkflowFactory.cs 中增加 StopWorkflowRuntime 事件处理函数: static void StopWorkflowRuntimeobject sender EventArgs e if _workflowRuntime null if _workflowRuntime.IsStarted try _workflowRuntime.StopRuntime catch ObjectDisposedException 以下是 WorkflowFactory.cs 文件的完整源代码,在第五章之前我们不会做更多的改变: using System using System.Collections.Generic using System.Linq using System.Text using System.Workflow.Runtime namespace WorkflowHost public static class WorkflowFactory //workflow runtime 的单一实例 private static WorkflowRuntime _workflowRuntime null private static object _syncRoot new object //工厂方法 public static WorkflowRuntime GetWorkflowRuntime //多线程环境下防止并发访问 lock _syncRoot if null _workflowRuntime AppDomain.CurrentDomain.ProcessExit new EventHandlerStopWorkflowRuntime AppDomain.CurrentDomain.DomainUnload new EventHandlerStopWorkflowRuntime _workflowRuntime new WorkflowRuntime _workflowRuntime.StartRuntime return _workflowRuntime static void StopWorkflowRuntimeobject sender EventArgs e if _workflowRuntime null if _workflowRuntime.IsStarted try _workflowRuntime.StopRuntime catch ObjectDisposedException 现在我们有了一个 workflow 运行时的创建工厂,然后我们将修改我们的主程序来使用它。
使用 workflow 运行时创建工厂 1.打开 Program.cs 文件并定位到如下代码上: WorkflowRuntime workflowRuntimenew WorkflowRuntime 2.把上面的代码修改成以下代码: WorkflowRuntime workflowRuntimeWorkflowFactory.GetWorkflowRuntime表 2-3 workflow 运行时的相关事件描述事件 功能Started 当 workflow 运行时启动后激发。
Stopped 当 workflow 运行时停止后激发。
WorkflowCompleted 当一个 workflow 实例完成后激发。
当一个 workflow 实例进入空闲状态时激发。
当 workflow 实例进入了空闲状态后,你就有机会把WorkflowIdled 他们从内存中卸载掉、存储到数据库并可在稍后 的时间把它们加载进内存。
当一个 workflow 实例被终止后激发。
在宿主中调 用一个 workflow 实例的 Terminate 方法、或通过WorkflowTerminated 一个 Terminate 活动、或当 workflow 运行时产生 一个未经捕获的异常时都会终止该 workflow。
我们还将在第四章和第五章介绍更多的事件。
在我们为上面的事件添加相应的事件处理程序时,你会看到生成的代码和上一章我们创建的基于工作台的顺序工作流应用程序中的代码完全一样(或几乎完全一 样)。
为了看看这些事件的作用,我们需要停止应用程序主线程一段时间。
因此,我们使用一个基于内核的自动重置事件。
一会儿后,我们将写出一些代码来使用上 述事件中的几个,你需要不时看看第一章中 PCodeFlow 项目中的 Program.cs 文件,对比它们的不同以及该写入什么样的代码。
尽管它们并不完全 相同,但你在两个程序中还是能找到相同的内容。
处理 workflow 运行时事件 1.启动 Visual Studio,打开项目的 Program.cs 源文件,定位到下面的代码上: WorkflowRuntime workflowRuntiemWorkflowFactory.GetWorkflowRuntime 2.假如你用过.NET 的委托,下面的代码你将非常熟悉。
我们需要为我们感兴趣的事件增加相应的事件处理程序。
我们现在就来为 workflow 空闲时和完 成后增加.