《WF编程》系列之5 - 漫游工作流:第一个工作流
《WF编程》系列之5 - 漫游工作流:第一个工作流
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属性:
{
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.
{
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活动.后边的章节会详述这类活动.
While活动的Condition属性包含CodeCondition和RuleConditionReference两个选项,它们表示两种描述条件的技术,前者需要一个返回Boolean值的方法,后者则使用规则.我们选择RuleConditionReference.规则条件(Rule Condition)是一个被命名的表达式,这个表达式返回true或者false,而且定义在外部文件(.rules)中.
Condition属性有两个子属性ConditionName和Expression.点击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执行工作流.工作流项目模板已经帮我们写好了代码.
{
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的WorkflowCompleted和WorkflowTerminated事件,这两个事件分别表示工作流正常结束和发生了异常被终止.使用CreateWorkflow方法并传递工作流类型来创建工作流实例.当工作流引擎异步执行我们的工作流时,我们需要通过AutoResetEvent对象阻止当前线程并等待工作流完成(否则控制台程序会在工作流运行之前退出).AutoResetEvent对象会阻止当前线程直到收到信号.
现在生成解决方案来看看效果: