《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属性:

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对象会阻止当前线程直到收到信号.

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

 

 

13 Comments

  1. 月风�� 说道:

    请问一下,
    我安装了.net framework 3.0、vs 2005、Visual Studio 2005 Extensions for Windows Workflow Foundation Beta 2_2(EN).exe,
    启动vs 2005时,提示安装的产品中有Workflow Foundation,
    但新建项目时,没有workflow模板,
    是怎么回事啊?

  2. kmoon 说道:

    很喜欢你的文章哈!有个小错误,
    Code活动的Condition属性应该是while活动吧

  3. 笑煞天 说道:

    @kmoon
    谢谢提醒,已经更正.

  4. 说道:

    非常非常棒!

    看到这里我才明白了工作流怎么实现。lz之前的文章还是很云里雾里的。这里终于明白了

    感觉微软这套wwf和我设计的一套数据流框架接近,我可以参考他。

  5. 不懂路 说道:

    不知道為何 8.5 的MSN不能用。。。。。。
    本人沒有接觸過.net,剛來。照著弄一下,成共嘍

  6. wjk333 说道:

    兄台真是好人,我在对工作流啥都不懂的情况下,看到这里,已经豁然开朗了。
    真是感谢。给我发邮件,我愿做你最真诚的小弟。

  7. 笨笨车 说道:

    第一个小例子总算是可以运行啦!在VSTS2008下,几个图释的地方不大一样,不过也不难找.楼主要继续努力写好文章呀!

  8. @笨笨车
    对哦,写这篇文章的时候VS2008还没有发布呢,VS2008中对工作流设计器进行了一些小的改动。

  9. 陈文奇 说道:

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

  10. 史文星 说道:

    不管怎么谢谢这位仁兄了~

  11. [...] 《WF编程》系列之5 – 漫游工作流:第一个工作流 [...]

Leave a Reply