昨夜飘风
昨 夜, 风, 飘 过; 枯 树, 叶, 飞 落。

源代码文件:

HelloWorkFlow.zip

所谓WF,就是.NET Framework 3.0的一个构成部分——Windows Workflow Foundation

工作流(workflow)是为了完成一些预定的目的,根据一组规则,而制定的一系列步骤。对于一个开发者来说,workflow则是将复杂的业务规则以及控制流程以图形化的方法声明出来,组成一个高度可视化的图形环境。

Workflow又不仅仅是一个开发环境,它还代表着一种不同的编程模型。它是一种能够更清晰的分离“what to do”以及“when to do it”的模型,这种分离可以使得我们能够在不影响what的情况下去改变whenWorkflow模型在解决人类交际问题的时候能够起到很瘧的作用~~

Microsoft提供了Windows Workflow Foundation来简化和增强.NET开发。它不是一个独立的应用程序,而是一个能够在我们的应用程序中启用workflow模型的设计。下面有一些使用它的好处,呵呵,我就不进行翻译了。

It provides a flexible and powerful framework for developing workflows. You can spend your time and energy developing your own framework, visual workflow designer, and runtime environment. Or you can use a foundation that Microsoft provides and spend your valuable time solving real business problems.

It promotes a consistent way to develop your applications. One workflow looks very similar to the next. This consistency in the programming model and tools improves your productivity when developing new applications and maintaining existing ones.

It supports sequential and state machine workflows. Sequential workflows are generally used for system interactions. State machine workflows are well-suited to solving problems that focus on human interaction.

It supports workflow persistence. The ability to save and later reload the state of a running workflow is especially important when modeling human interactions.

It supports problem solving using a domain-specific model. Microsoft encourages you to develop your own custom activity components. Each custom component addresses a problem that is specific to your problem domain and uses terminology that is common to the domain.

It provides a complete workflow ecosystem. In addition to the workflow runtime itself, Microsoft also provides a suite of standard activities, workflow persistence, workflow monitoring and tracking, and a workflow designer that is integrated with Visual Studio which you can also host in your own applications.

It is free of charge. Because of this and its tight integration with Visual Studio, it will become the de facto standard workflow framework for Windows developers. A growing community of other WF developers is already in place. They are already sharing their ideas, their custom activity components, and other code.

开发环境

最好的选择是Visual Studio 2008 RTM。当然,使用VS2005也是可以的。详细的列表如下:

Visual Studio 2005 Team System, Enterprise, Professional或者Standard版本。Express版无效;

.NET Framework 3.0

Windows SDK 6.0

Windows Workflow add-in for Visual Studio

除了第一个需要购买,其余三个都可以在MS的官方网站上下载得到。在我的整个WF读书笔记之中,均是采用Visual Studio 2008 beta2 Professional为运行环境(目前它是免费的^_^)。

Hello Workflow

我们学习任意一项新的编程领域的时候都会引入经典的Hello World程序,在这里也不例外。我们就以“Hello Workflow”来开始我们的WF之旅~~

启动VS2008File->New->Project,选择如图所示的Sequential Workflow Console Application并给它选择一个路径,点击确定。
 

初始化完毕之后,请展开Solution Explorer中的References项,其中WF所必须的引用程序集有:

System.Workflow.Activities

System.Workflow.ComponentModel

System.Workflow.Runtime

项目模板建立了一个叫做Program.cs的文件。由于我们建立的是一个控制台程序,这个文件包含一个Main方法,作为程序的入口。

下面我们再来看看workflow的设计器。它看起来很像我们早期设计算法的时候采用的流程图,有开始和结束两个端点。这个设计器就像一个“画布”,我们在它的上面“绘制”我们的workflow。当然我们也可以完全以代码的形式来完成这些工作,但那无疑是低效而且落后的。从Toolbox中我们可以用拖放的方式,将一个个activity补充到workflow画布上来。

所谓的activity,就是标志着工作流中的一个步骤,它也是构造WF工作流的砖瓦。所有的activity都是直接或间接派生自System.Workflow.ComponentModel.Activity基类。MS提供了一组标准的activity供我们使用,但我们也可以随心所欲自己定义新的activity来。

这个例子中的工作流是顺序工作流(sequential workflow),因而activity的顺序就决定了它们被执行的次序。请从Toolbox中拖动一个CodeActivity,放置在工作流中。
 

实际中它的类名是CodeActivity,这个实例的名字默认是codeActivity1。在右上角应该有一个红色的惊叹号,这表明有一些必要的属性没有被设置。点击它我们可以看到“Property ExecuteCode is not set.”这样的错误信息,我们需要为它设置合适的值。在属性窗口中,找到它的ExecuteCode,填入codeActivity1_ExecuteCode并回车(也可以直接双击这个属性的名字),一个空的事件句柄就被创建了,并且Workflow1.cs也会随之打开。为这个事件添加如下的代码:

    Console.WriteLine("Hello Workflow!");

如此,这个CodeActivity的执行代码就搞定了。让我们再打开Program.cs,可以看到Main方法中已经添加了一串代码。关于它的解释请自行参阅MSDN,里面用到了不少.NET 3.0的新特性(比如匿名委托这样的)。我们在Main方法的结尾添加下面的两行代码:

    Console.WriteLine("Press ENTER to exit");

    Console.ReadLine();

按下F5,看看执行的结果吧 ^_^

传递参数(Passing Parameters

如果一个工作流不能接受外接参数输入的话,那它的功能就太圡了。将参数传送进工作流也是一项最基本的WF技能,使得我们可以从外界影响工作流的工作。下面我们改进一下Hello Workflow程序,让它能够接受外界的参数,变成一个“susan说”~~~

首先,我们需要在workflow类里添加可写属性。打开Workflow1.cs的代码,将Workflow1类的代码改写如下:

public sealed partial class Workflow1: SequentialWorkflowActivity

{

    private string _person = string.Empty;

    private string _message = string.Empty;

    ///<summary>

    /// The target of greeting

    ///</summary>

    public string Person

    {

        get { return _person; }

        set { _person = value; }

    }

    ///<summary>

    /// The greeting message

    ///</summary>

    public string Message

    {

        get { return _message; }

        set { _message = value; }

    }

public Workflow1()

{

InitializeComponent();

}

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)

    {

        // Displays the variable greeting

        Console.WriteLine("{0} said: {1}",_person,_message);

    }

此时的工作流就可以接受PersonMessage两个入口参数(注意,入口参数的名称与定义的属性名必须完全一致

紧接着,我们需要在运行时(runtime)调用此workflow的时候为其参数赋值。打开Program.cs,添加下面加粗的部分代码。

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

using System.Workflow.Runtime;

using System.Workflow.Runtime.Hosting;

namespace HelloWorkFlow

{

    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();

                };

                // Create a dictionary with input arguments

                Dictionary<string, object> wfArguments = new Dictionary<string, object>();

                wfArguments.Add("Person", "SpadeQ");

                wfArguments.Add("Message", "Welcome to Nocturne Studio!");

 

                WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(HelloWorkFlow.Workflow1),wfArguments);

                instance.Start();

                waitHandle.WaitOne();

            }

            Console.WriteLine("Press ENTER to exit");

            Console.ReadLine();

        }

    }

}

输入参数以泛型Dictionary对象的形式传递给工作流。此Dictionary必须以string类型为key,以object类型为value,构成每一个参数项。一旦Dictionary对象创建完毕,我们可以用Add方法来为每个参数赋值。

再次提醒一下,Dictionary每一个key的值必须与工作流中定义的属性名完全一致,它们就是以变量名来进行匹配的。

执行此程序,我们可以看到参数成功地传递到工作流的内部了J

posted on 2008-02-25 09:50  昨夜飘风  阅读(3174)  评论(1编辑  收藏  举报