第一部分 简介
Workflow Foundation 包含在 .net4.0 中(也简称为 WF4.0 )是一个用于建立工作流应用的新模式。它已经被重新设计,在这一部分,你可以设计一些简单的工作流并且学习一些概念。在随后的章节里,你探索到 WF4.0 提供的功能时,你可以开发更多复杂的解决方案。
第一章 建立一个简单的工作流
让我们开始建立一个简单的工作流。启动 VS2010 单击 新项目连接。在已安装的模版下,导航到 Visual C#,workflow 你可以看见 4 个以提供的模板。选择 Workflow Console application ,输入名称为 chapter01 ,为这个解决方案选择合适的路径。
图 1-1 创建一个新的工作流项目
一个简单的工作流
模板生成了一个 program.cs 的文件,他实现了控制台程序。他还生成了一个 Workflow1.xaml 文件,他在你的工作流中定义了活动,如果你曾经开发或 Windows Presentation Framework ( WPF )应用,你可能熟悉 xaml ,他的语法类似 xml ,可以添加 Labels , textboxes 和 grids ,不过,这个文件将包含您的工作流的元素, VS2010 提供了一个设计器,是您可以在图形界面下查看和编辑这些活动。
观察 IDE
图 1-2 显示了一个 vs2010 的典型布局,左边的工具箱包含了内置的和您自定义的活动,这里已经展开了一些常用的活动组,解决方案浏览器和属性窗口在右边,底部窗口错误清单和输出窗口。
图 2 :标准的 vs2010IDE
WF4.0 设计器在中间,右下方的控件可以缩放。在 4.0 的版本中工作流的设计往往有点长,这里有一个方便的功能就是查看大图片或寻找特定的活动。在底部有三个控件,左边开始查看变量,参数,和导入的组件。当你单击变量控件,一个窗口弹出显示存在的变量,如图 1-3 所示,再次单击控件关闭窗口。
图 1-3 查看工作流的变量
把你的工作流想象成是一个类,变量就是类的成员。你可以用他们来存储数据和在活动之间共享数据。你可以定义变量,无论实在顶级活动还是一个特定的活动(子活动)中。参数类似变量,但是他们多了一个义务,将数据传递进来或出去。你可以把他们想象成方法的参数。
参数窗口如图 1-4 所示,注意 Direction 这一列,他定义了数据是被传进工作流还是被传出工作流。
图 1-4 查看工作流参数
设计工作流
最初的工作流设计器是空的,你需要把活动拖到上面定义工作流的行为。这个项目最初只会显示问候语 “helloworld” ,稍后,你将添加一些活动到他上面。首先,拖一个 Sequence 活动到设计器上。再拖一个 writeline 活动到 Sequence 活动上,如图 1-5 所示
图 1-5 添加一个 WriteLine 活动
属性窗口如图 1-6 所示
图 1-6 WriteLine 活动的的属性窗口
DisplayName 属性是一个文字描述,你可以给她一个有意义的名字,因为你的工作流中包含不止一个 WriteLine 活动,这样不至于忘记某个活动是干什么的。把他改成 “Hello” ,将如下字符串输入到 Text 属性:
“hello , world”
text 属性可以接受任何返回值为 string 的表达式。单击右边的按钮,将显示一个对话框让你输入表达式。
默认情况下,控制台会输出字符串,你可以从 TextWriter 派生一个类,如果你想有一个不同的实现的话,这将在第九章详细展示。
回顾 Program.cs
打开 program.cs 文件,他将实现控制台程序并运行工作流,从模板默认生成的实现如清单 1-1 所示 :
清单 1-1 默认的 Program.cs
using System;
using System.Linq;
using System.Activities;
using System.Activities.Statements;
namespace Chapter01
{
class Program
{
static void Main(string[] args)
{
WorkflowInvoker.Invoke(new Workflow1());
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
}
}
}
WorkflowInvoker 静态类用于启动由 Workflow1 类定义的工作流。粗体斜字是自己加上去的而不是模板生成的。
我加入这两行是因为要控制程序不会在你还没有机会看到输出就已经退出了。你可以在你的项目里加入这个代码。
运行程序
现在按 F5 运行程序,结果就像这样:
Hello, World!
Press ENTER to exit
添加处理元件
WF4.0 提供了一些处理元件比如 If , While , Assign , Sequence 等等,接下来,我们来学习他们的用法,打开 Workflow1.asmx 文件。
使用变量
在 WF4.0 中,你必须定义需要的变量才能将他们用在工作流的元素中,你需要两个变量,一个说明需要多少钟声,另一个作为计数器记录当前已经响了多少下。单击变量按钮,如果变量窗口如图 1-3 所示,表示在这个范围内还没有任何变量定义。
单击 Sequence 活动,变量窗口如图 1-7 所示
图 1-7 当前范围内的变量窗口
单击创建变量连接,输入变量名 “counter” 选择类型为 Int32 ,此时变量只能在 Sequence 和他的子活动中使用。输入默认值为 1 ,此时变量窗口如图 1-8
图 1-8 变量窗口有了一个新变量
属性窗口也有同样的作用 ( 如图 1-9) ,你可以在属性窗口输入变量也可以在变量窗口输入。
图 1-9 选中变量的属性窗口
再次单击创建变量连接,这一次,使用属性窗口输入变量属性,输入名称为 numberBells ,类型为 Int32 ,范围是 Sequence ,单击 default 右边的按钮,将显示一个表达式编辑器,如图 1-10
图 1-10 表达式编辑器
————————————————————————————————————————
注释:关羽 WF4.0 的一件值得关注的事情是,他依赖于很多的表达式,很多属性可以使用表达式来定义,但是窗口通常都不能写下足够长的语句,为了解决这个问题,通过单击右方的按钮获得更大空间的表达式输入窗口。表达式可以是变量,参数,系统函数,或是你自己的代码。
————————————————————————————————————————
默认值属性输入 DateAndTime.Now.Hour ,这回设置 numberBeels 变量的值为当前时间的小时数,变量窗口如图 1-11 所示
图 1-11 最总的变量窗口
If
DateAndTime 类的 Hour 成员返回基于 24 小时制的小时数,比如, 2PM ,他将返回 14 ,所以你必须调整他,因为你只要敲两下,而不是 14 下,你需要这样写代码
if (numberBells > 12)
numberBells - = 12;
刘军的笔记,这样行不行: number %=12 ;
但是 在WF4.0 中你需要使用一个If 和一个Assign 活动来完成,拖动一个If 活动放在Hello 活动的下方,界面如图1-12 所示
图1-12 添加一个if 活动
————————————————————————————————————————
注释:请注意图中的红色圆圈错误,如果你的鼠标悬停在他上面,他将显示相关的警告或错误,这个错误让你知道你没有为 If 活动指定条件属性。 Sequence 活动上的警告只是简单的告诉你他的一个或多个子活动有错误。
————————————————————————————————————————
在属性窗口中将 DisplayName 属性改变为 Adjust for PM , If 活动包含三个元素,条件属性指定了判断逻辑,根据条件的 true 或 false 决定一个分支。
Assign
拖一个 Assign 活动到 then 上面, assign 活动允许你分配一个值到变量或参数,如图 1-13 所示
图 13 定义一个 assign 活动
To 和 value 属性都可以接受一个表达式,你可以在输入框输入表达式也可以在右侧的按钮单击开后弹出的窗口中输入表达式, To 属性输入 numberBells , value 表达式输入 numberBells-12 ,属性窗口如图 1-14 所示
图 1-14 assign 活动的属性窗口
许多活动是复合活动,也就是说他们可以包含其他活动, If 活动就是一个很好的例子,当你设计一个复杂的工作流时,你可以通过导航在工作流中设计好几层。
While
现在你可以添加一个 While 活动来敲响时钟了,拖一个 While 活动到 Adjust for PM 活动的下面,设置 DisplayName 属性为 Sound Bells ,此时界面如图 1-15 ,
图 1-15 定义一个 While 活动
在一个 While 活动中,当条件为真是,主体可以一直执行下去,条件为 true ,活动就会一只执行下去,知道条件为 false 。
————————————————————————————————————————
记: DoWhile 活动和 While 活动类似,所不同的在于 DoWhile 第一次执行时无论条件是否为 true 都会执行,而 While 不是这样。
————————————————————————————————————————
输入条件为 counter <= numberBells ,拖动一个 Sequence 活动到主体上,设置 DisplayName 属性为 Sound Bell 如图 1-16 所示
图 1-16 一个 While 活动包含一个 Sequence 活动
Sequence
你可以拖三个活动到 Sound Bell 上,在这个过程中,你不会真的听到钟声,相反,你会向控制台写入一行文字,拖一个 WriteLine 活动到 Sound Bell 活动,在 Text 属性里,输入
counter.ToString ()
他会把 counter 的当前值写入到控制台,这是拖一个 assign 活动到 writeline 活动的下面, to 属性输入 counter , value 属性输入 counter+1
Delay
最后,拖一个 Delay 活动到 assign 活动的下面, Delay 活动可以暂停工作流一段指定的时间, Delay 活动唯一的属性是 Duration ,他指定暂停多长时间,它可以用一个 TimeSpan 类来指定,表达式如下所示
TimeSpan.FromSeconds ( 1 )
界面如图 1-17 所示
图 1-17 完全的 Sequence 界面