1.3      开发我们的第一个工作流

也许你曾经在这样的产品经理手下搞过开发:他总是在你身边转悠,并不时的问一句“你还没做完吗?”。在这一部分,我们将用一个简单的Windows Workflow程序把这个招人烦的产品经理替换掉。这个例程无法向你展示WF平台的全部功能,但它可以让你领略到如何用WF创建并运行工作流。

在开始之前,我们需要下载并安装.NET 3.0框架。安装程序可以在 http://netfx3.com 找到。Visual Studio 2005的所有版本都支持在.NET 3.0框架上的开发。我们还需要下载并安装Visual Studio 2005 Extensions for Windows Workflow Foundation。这个扩展包也可以在 http://netfx3.com 找到。但是这个扩展包不支持Visual Studio 2005 的Express版本。

首先,用Visual Studio新建一个Workflow工程(File | New Project)。我们选择使用C#开发,选择Sequential Workflow Console Application(顺序工作流控制台应用程序)模板(参见下面的截屏图)。模板为我们生成的工程包含有:对所有必要的WF程序集的引用,一个空工作流和一个用来驱动工作流的Program.cs文件。右键单击这个工作流,选择Delete(删除)操作,这样我们就能从零开始编制一个工作流了。

我们现在可以在Solution Explorer(解决方案管理器)窗口中右键单击工程文件,选择Add New Item(添加新项目)。在可添加项目列表中,我们选择Sequential Workflow(with code separation)(顺序工作流-代码分离),然后把这个新项目命名为workflow1.xoml(请见下面的截屏图)。这个XOML文件中就是用XAML标记码定义的我们的工作流。

如果展开Workflow1.xoml节点,我们就会看到包含一个分部类的代码旁置文件(Workflow1.xoml.cs)。前面说过,这个分部类将与XAML标记码定义的类共同生成一个完整类型。在下面的代码中,我们对Workflow1.xoml.cs中的类做了修改,添加了一个IsFixed属性及其支持字段。

public partial class Workflow1 : SequentialWorkflowActivity
{
private bool _isFixed; public bool IsFixed
{
get { return _isFixed; } set { _isFixed = value; }
}
}

如果双击.xoml文件,设计器窗口就会打开。此时如果Toolbox窗口还没有打开,我们可以用快捷键Ctrl+Alt+X打开它。我们可以从Toolbox中拖出一个While活动,并放置到工作流的起始点和终止点之间。While活动会重复执行其内部的子任务,直到某个条件得到满足为止。再拖出一个Code活动,把它放到While里面。现在,我们的设计器就是下面这个样子:

你看到了吗?每个活动都带着一个红叹号点。这就是说,两个活动的有效性验证都没通过。我们可以把鼠标停在叹号点上,点开智能标记后就能看到验证错误。如果现在就执行编译操作,验证错误就会作为编译错误出现在错误提示窗口中。让我们动手来修复这些错误。

Code活动要求我们为其ExecuteCode事件分配一个事件处理函数。我们可以在Code活动的Properties窗口中(用F4快捷键打开)完成这项分配操作。双击ExecuteCode属性旁边的空白处,相应的代码旁置文件就会打开,里面也已经有了一个自动生成的事件处理函数框架。我们把下面这段代码放到框架中。这段代码向用户询问软件缺陷是否已修复,然后等待用户按下一个键。如果用户按了“y”键,程序会将_isFixed字段设置为true。

private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("Is the bug fixed?"); Char answer = Console.ReadKey().KeyChar; answer = Char.ToLower(answer); if (answer == 'y')
{
_isFixed = true;
}
else
{
Console.WriteLine();
Console.WriteLine("Get back to work!");
Console.WriteLine();
} }

Code活动的验证已经通过了,让我们来对付While活动。While活动需要一个有效的Condition(条件)属性。基本活动库中有好几个活动在执行时都需要“条件”,这其中就包括IfElse、ConditionedActivityGroup以及Replicator活动。第9章将会深入讨论条件与规则。

设置Condition属性的方法很简单:在Properties窗口中打开Condition属性旁边的下拉列表框,在CodeConditionRuleConditionReference中二选一。这两个供选项代表了两个不同的条件表述技术,前者用代码表述(一个返回布尔值的方法),后者用规则。这里选择RuleConditionReference一项。规则条件是一个命名表达式,它的评估结果是true或false,它能够存储在独立的.rules外部文件中,这样易于维护。现在,Condition属性旁边出现了一个加号,点击这个加号可以展开属性编辑器。

Condition属性被展开后,Properties窗口允许我们对ConditionName(条件名称)和Expression(表达式)进行设置。点击Condition旁边的省略号(…)按钮,Select Condition(选择条件)对话框就会弹出来。

点击New Condition…(新条件…)按钮会弹出下面的Rule Condition Editor(规则条件编辑器)。

我们打算让While活动循环执行直到缺陷被修复,因此我们输入的规则是 !this.IsFixed(编辑器自带的IntelliSense功能可以让我们偷点懒),然后点OK(确定)按钮。当返回到Select Condition对话框,可以看到编辑器已经把我们的条件命名为Condition1。请选择Condition1并点击OK。此时已经完成了对While活动ConditionNameExpression的设置,也通过了有效性验证。

现在打开Program.cs文件,这里的Main方法是控制台程序的入口点。我们需要承载WF运行时,并让它来执行我们的工作流。工作流工程模板中已经提供了所有我们需要的模板代码。请看下面的代码:

class Program
{
static void Main(string[] args)
{
WorkflowRuntime workflowRuntime = new WorkflowRuntime(); workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs> (workflowRuntime_WorkflowCompleted); workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs> (workflowRuntime_WorkflowTerminated); WorkflowInstance instance; instance = workflowRuntime.CreateWorkflow(typeof(Workflow1)); instance.Start(); waitHandle.WaitOne();
} static void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message); waitHandle.Set();
} static void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
waitHandle.Set();
} static AutoResetEvent waitHandle = new AutoResetEvent(false);
}

第一步是生成一个WorkflowRuntime实例。代码中已经为运行时指定了两个事件处理函数,因此如果工作流终止(因为异常)或结束了,我们都能够得到相应的通知。随后调用CreateWorkflow方法生成了一个缺陷修复工作流的实例,调用参数就是我们的工作流类型。因为工作流引擎是以异步方式执行工作流,我们就必须用一个AutoResetEvent对象将主线程阻塞,并等待工作流结束(不然的话,这个控制台程序可能会在工作流开始执行前就退出了)。AutoResetEvent对象会阻塞一个线程,直到该对象进入信号状态,而我们恰好是在前面提到的两个事件处理函数中调用AutoResetEvent对象的Set方法将其设为信号状态。

现在我们可以生成这个工作流解决方案,然后在命令行中运行它的可执行文件。

1.4      总结

软件开发者们从一开始就不断地使用工作流对业务流程进行建模与实现。在这期间,我们已经知道了工作流可能会长时间地运行,并经常需要得到用户的输入信息。通过创建一个健壮的工作流来应对这些挑战是一项令人望而生畏的任务。一种理想的工作流创建范例是将工作流的定义与工作流的执行引擎分离开。

一旦将工作流的定义与执行引擎分离,我们就可以通过构建工作流组件的方式编制出域特定语言。如果一个业务人员能够理解域特定语言,那么在忽略掉异常处理和状态追踪这些细节的情况下,他同样能够理解一个工作流。

Windows Workflow为微软平台带来了一个工作流执行引擎和一系列工作流开发工具。WF引擎的执行指令就是活动,我们可以利用图形化的设计器、XAML、代码或者它们三者的组合,对活动进行一番编排。WF还提供了一些工作流引擎所需的服务,这包括持久化服务、线程服务以及事务服务。因此我们可以说:用WF搞工作流开发,前途一片光明。

章节链接:

【翻译习作】 Windows Workflow Foundation程序开发

【翻译习作】 Windows Workflow Foundation程序开发-前言

【翻译习作】 Windows Workflow Foundation程序开发-第一章01

【翻译习作】 Windows Workflow Foundation程序开发-第一章02

【翻译习作】 Windows Workflow Foundation程序开发-第一章03

【翻译习作】 Windows Workflow Foundation程序开发-第一章04

【翻译习作】 Windows Workflow Foundation程序开发-第一章05的更多相关文章

  1. 【翻译习作】 Windows Workflow Foundation程序开发-第一章04

    1.2.3  Windows Workflow运行时 从Windows Workflow的角度看,可以将工作流活动当成是交给一个工作流处理器去执行的一系列指令或操作码.在Windows Workflo ...

  2. 【翻译习作】 Windows Workflow Foundation程序开发-第一章03

    1.2.2.Visual Studio 2005扩展包 微软也为Windows Workflow开发者提供了Visual Studio 2005扩展包.扩展包将许多功能集成到Visual Studio ...

  3. 【翻译习作】 Windows Workflow Foundation程序开发-第一章02

    1.2      Windows Workflow概览 微软的Windows Workflow Foundation(简称WF)是.NET框架3.0版的一部分..NET3.0其它主要部分是Window ...

  4. 【翻译习作】 Windows Workflow Foundation程序开发-第一章01

    第 1 章    欢迎来到工作流的世界 …思想如蝴蝶般飞到我身边 —— Gossard / Vedder (译注:Gossard与Vedder是来自Pearl Jam乐队的2名乐手,该句出自他们的歌曲 ...

  5. 【翻译习作】 Windows Workflow Foundation程序开发

    近期整理硬盘,把09年的翻译习作<Windows Workflow Foundation程序开发>找出来了.现在又把译文过了一遍,做了些修改,贴出来献丑了.原书是<Programmi ...

  6. 【翻译习作】 Windows Workflow Foundation程序开发-前言

    Windows Workflow Foundation程序开发-基于XAML和C#的WF实战技术与例程 ——C#程序员的WF功能与编程接口技术指导 前言 Windows Workflow Founda ...

  7. 你还记得windows workflow foundation吗

    很多年前,windows workflow foundation还叫WWF,而直译过来的名称让很多人以为它就是用来开发工作流或者干脆就是审批流的. 博主当年还是个懵懂的少年,却也知道微软不会大力推一个 ...

  8. Workflow-Microsoft:Windows Workflow Foundation

    ylbtech-Workflow-Microsoft:Windows Workflow Foundation 1. Windows Workflow Foundation返回顶部 1.1. Windo ...

  9. 微信小程序开发-第一弹

    前言:       本篇文章为大家详细介绍微信小程序开发第一篇,后续步骤会逐步更新,欢迎大家关注. 第一步  注册        1.1 打开网址 https://mp.weixin.qq.com/  ...

随机推荐

  1. RHCE7.0练习题汇总[转]

    RHCE7.0练习题汇总38 RHCSA部分 关于密码破解,在上午的考试中需要我们自己安装图形化界面和破解root密码,root的密码按照题目的要求来进行修改.可以使用单用户模式或者使用上课讲的re. ...

  2. winform实现word转换为PDF(.doc)

    注意:实现word转换为PDF文件,本人安装Office为2013; word以后缀为.doc为例实现文件类型转换,具体方式如下所示: 实现步骤: 1.添加命名空间引用——using Microsof ...

  3. 关于snprintf的一个warning

    在编一段代码时用到snprintf,有个很奇怪的warning 编译提示: warning C4013: 'snprintf' undefined; assuming extern returning ...

  4. 在 Perl 中使用 Getopt::Long 模块来接收用户命令行参数

    我们在linux常常用到一个程序需要加入参数,现在了解一下 perl 中的有关控制参数的模块 Getopt::Long ,比直接使用 @ARGV 的数组强大多了.我想大家知道在 Linux 中有的参数 ...

  5. spark1.4加载mysql数据 创建Dataframe及join操作连接方法问题

    首先我们使用新的API方法连接mysql加载数据 创建DF import org.apache.spark.sql.DataFrame import org.apache.spark.{SparkCo ...

  6. 在dom4j中使用XPath

    package com.wzh.test.xpath; import java.io.File; import org.dom4j.Document; import org.dom4j.Documen ...

  7. Xcode 的正确打开方式——Debugging(转载)

    Xcode 的正确打开方式——Debugging   程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能 ...

  8. codeblocks调试快捷键说明

    使用codeblocks避免不了快捷键: 在调试程序的时候: 首先在view->toolbar->debugger调出来:快捷方式可以自己看 RUN to Cursor  :F4 单步调试 ...

  9. CRM IFRAME 显示地图

    作者:卞功鑫  ,转载请保留.http://www.cnblogs.com/BinBinGo/p/5274409.html 需要背景: 现在已经有经纬度,需要在地图上显示出来. 环境: CRM 4.0 ...

  10. java socket通讯(一) 入门示例

    一.入门 要想学习socket通讯,首先得知道tcp/ip和udp连接,具体可参考浅谈TCP/IP 和 UDP的区别 二.示例 首先新建了一个java工程,包括两个部分,客户端SocketClient ...