代码改变世界

《WF编程》系列之5 - 漫游工作流:第一个工作流

2007-03-31 09:43  Windie Chai  阅读(...)  评论(...编辑  收藏

1.2.4 第一个工作流

还记得项目经理经常问我”做完了吗?”.在这一节中,我们把烦人的项目经理换成简单的工作流程序.这个例子并没有用到工作流平台的所有的功能,只是简单的创建并运行一个工作流.

在开始之前,我们需要安装.NET 3.0 framework.支持.NET 3.0 framework的开发工具包括Visual Studio 2005全部版本.除此之外还需要安装Visual Studio 2005 Extensions for Windows Worfkflow Foundation.需要注意的是这个扩展不兼容Visual Studio 2005 Express版.如需下载,请访问http://netfx3.com.

首先,使用Visual Studio创建一个Workflow项目(文件|新建|Visual C#|Workflow),选择的Sequential Workflow Console Application模板.此模板创建的项目会引用适当的WF程序集并包含一个空白工作流(Workflow1.xoml)和一个用来驱动工作流的Program.cs文件.右键单击空白工作流然后选择删除,我们自己来添加一个.

 

在解决方案资源管理器面板中右键单击项目文件,选择添加|新建项.选择Sequential Workflow (with code separation)并命名为workflow1.xoml.

这个XOML文件包含了工作流的XAML定义.

 

点击Workflow1.xoml前边的+来展开文件列表,会看到一个C#代码文件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文件来打开工作流设计器,从工具箱(Ctrl+Alt+X)中拖拽一个While活动到工作流开始和结束的活动之间.While活动会循环执行它的子活动一直到条件复合为止.之后再拖拽一个Code活动到While活动内部:

 

我们注意到这两个活动都显示惊叹号,说明它们都验证失败了.把鼠标移到惊叹号上方,智能提示会告诉我们错误的详细信息,而且无法通过编译.现在我们就来修正这些错误.

Code活动必须为其ExecuteCode事件指定一个event handler.在Code活动的属性面板(F4)中双击ExecuteCode事件,将会打开Code-beside文件并自动添加了event handler.我们将下边的代码添加到event handler中.这段代码会询问用户是否修复了bug并获取按键,如果用户输入”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,ConditionedActivityGroupReplicator活动.后边的章节会详述这类活动.

While活动的Condition属性包含CodeConditionRuleConditionReference两个选项,它们表示两种描述条件的技术,前者需要一个返回Boolean值的方法,后者则使用规则.我们选择RuleConditionReference.规则条件(Rule Condition)是一个被命名的表达式,这个表达式返回true或者false,而且定义在外部文件(.rules)中.

Condition属性有两个子属性ConditionNameExpression.点击ConditionName旁边的省略号按钮,会弹出一个Select Condition对话框.

 

点击”New…”按钮来弹出Rule Condition Editor对话框.

 

我们想要While活动一直循环直到bug被修复.所以规则应该是!this.IsFixed.输入条件(编辑器可以智能感知)之后可以点击OK.返回Select Condition对话框后,可以看到编辑器中出现了一个条件叫做Condition1.选择Condition1然后点击OK完成.现在While活动的ConditionName和Expression属性都设置了正确的值并且通过了验证.

接着打开Program.cs文件,这个文件包含了控制台应用程序的入口点-Main方法.我们需要将WF Runtime托管到这里并让Runtime执行工作流.工作流项目模板已经帮我们写好了代码.

 

class Program

    {

        
static void Main(string[] args)

        {

            
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())

            {

                AutoResetEvent waitHandle 
= new AutoResetEvent(false);

                workflowRuntime.WorkflowCompleted 
+= delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};

                workflowRuntime.WorkflowTerminated 
+= delegate(object sender, WorkflowTerminatedEventArgs e)

                {

                    Console.WriteLine(e.Exception.Message);

                    waitHandle.Set();

                };

 

                WorkflowInstance instance 
= workflowRuntime.CreateWorkflow(typeof(Chapter1_bugflow.Workflow1));

                instance.Start();

 

                waitHandle.WaitOne();

            }

        }

    }

这段代码首先要做的是初始化WorkflowRuntime的实例.然后设置Runtime的WorkflowCompletedWorkflowTerminated事件,这两个事件分别表示工作流正常结束和发生了异常被终止.使用CreateWorkflow方法并传递工作流类型来创建工作流实例.当工作流引擎异步执行我们的工作流时,我们需要通过AutoResetEvent对象阻止当前线程并等待工作流完成(否则控制台程序会在工作流运行之前退出).AutoResetEvent对象会阻止当前线程直到收到信号.

现在生成解决方案来看看效果: