逻辑流活动.docx
《逻辑流活动.docx》由会员分享,可在线阅读,更多相关《逻辑流活动.docx(11页珍藏版)》请在冰豆网上搜索。
逻辑流活动
逻辑流活动
对于任何一个计算机系统的主要组成部分来说,都应具有根据运行时的条件做出判断以执行不同的任务的能力。
在本章,我们将演示要求我们应付if/else场景及基本的循环的一些工作流活动。
学习完本章,你将掌握:
1.学会怎样使用IfElse活动来执行条件表达式
2.学会怎样使用While活动来执行循环
3.理解Replicator活动是怎样来模拟for循环的,以及它的使用方法。
我们已经看到过怎样执行工作流内部和外部的代码,已经知道怎样处理异常,暂停进程,在事情脱离控制时终止我们的工作流。
但无疑对于任何一个计算机系统的主要组成部分来说,都应具有根据运行时的条件做出判断以执行不同的任务的能力。
在本章,我们将演示要求我们应付if/else场景及基本的循环的一些工作流活动。
条件及条件处理
现在,你可能不会感到奇怪,你发现WF提供了基于运行时的条件进行逻辑处理控制流的活动。
毕竟,假如WF提供了活动去抛出并捕获异常,那它为什么就没有相应的活动来根据工作流的执行情况进行检测并根据它们获取的结果作出决策呢?
我们将在本章中进行测试的活动包括IfElse活动、While活动和Replicator活动。
IfElse活动的作用是测试一个条件并根据测试结果执行不同的工作流路径。
While活动用来执行一个While循环。
而对于for循环,则是使用Replicator活动来完成。
现在通过本章的示例应用程序开始我们的学习。
备注:
在本章你将依靠CodeCondition来进行条件的处理,它(CodeCondition)的意思是你将写下C#代码来处理条件表达式。
在12章(“策略和规则”)中,你将使用RuleCondition来对条件表达式的值进行处理,RuleCondition使用了WF的基于规则的处理方式。
两种方式都同样有效。
使用IfElse活动创建QuestionFlow工作流
1.下载本章源代码,打开IfElseQuestioner文件夹中的解决方案。
2.看看VisualStudio解决方案资源管理器,你会看到解决方案的层次结构和前一章中的相似。
主应用程序的文件位置在Questioner项目中,而宿主通信服务文件的位置则在QuestionService项目中。
为使你把注意力放到工作流上,我已经创建了服务接口(具体过程参见前一章):
IQuestionService,并且使用wca.exe工具(使用方法参见前一章)生成了一个必需的通信活动:
SendReponseDataToHost。
现在,找到QuestionFlow项目的Workflow1.cs文件并在视图设计器中打开它。
3.从工具箱中拖拽一个IfElse活动到设计器界面上。
4.你会看到一个内含感叹号(!
)标记的红色圆圈,这是提醒你还需要更多的信息才能编译你的工作流。
其实,缺少的就是条件表达式!
选中ifElseActivity1的左边分支以便在VisualStudio的属性面板上呈现该活动的属性。
选中它的Condition属性以激活它的下拉列表框,然后从列表中选择代码条件。
备注:
你通常有两种方式来对条件表达式进行选择:
code(代码)和rules-based(基于规则)。
我们这里将使用基于代码的条件表达式,基于规则的技术将保留到第12章(策略活动)进行学习。
5.展开显示的Condition属性,输入AskQuestion1,然后按下回车键,VisualStudio这就为你插入了AskQuestion1的事件处理程序并会切换到代码视图下。
现在,重新回到工作流视图设计器上,你还要把更多的活动添加到你的工作流中。
6.拖拽一个Code活动到设计器界面上,并把它放到ifElseActivity1的右边分支上。
7.指定它的ExecuteCode属性值为NegateQ1。
当VisualStudio插入了NegateQ1事件出现程序后,重新回工作流视图设计器界面上。
8.重复步骤6和步骤7,在ifElseActivity1的左边分支上也添加一个Code活动。
指定它的ExecuteCode属性值为AffirmQ1,但是,当VisualStudio插入了AffirmQ1事件出现程序后,不要切换回工作流视图设计器界面上。
相反,我们要添加一些代码。
9.我们现在需要为该工作流类添加一些属性,当我们起动工作流进程时可把它们作为参数。
在Workflow1的构造器的下面,添加下面的代码,它们包含有工作流将问到的三个问题:
privatestring[]_questions=null;
publicstring[]Questions
{
get{return_questions;}
set{_questions=value;}
}
10.我们也需要添加一个Dependent属性,它用来告知这些问题彼此是否是相关的。
在上面所添加的代码下,添加如下代码:
privatebool_dependent=true;
publicboolDependent
{
get{return_dependent;}
set{_dependent=value;}
}
11.问题回答的结果是一些Boolean值,在传回给宿主应用程序前需要保存到某些地方。
因此,在上面所插入的代码下添加该字段:
privatebool[]_response=null;
12.该_response字段没有被初始化,因此找到Workflow1的构造器,在里面的InitializeComponent方法下面添加如下的代码:
//Initializereturnvector.
_response=newbool[3];
_response[0]=false;
_response[1]=false;
_response[2]=false;
13.现在找到VisualStudio为你添加的AskQuestion1事件处理程序(eventhandler)。
在该事件处理程序中添加下面的代码:
//Askthequestion!
DialogResultresult=MessageBox.Show(Questions[0],"Questioner:
",
MessageBoxButtons.YesNo,MessageBoxIcon.Question);
e.Result=(result==DialogResult.Yes);
14.对于NegateQ1事件处理程序,则添加下面的代码:
//Negateanswer.
_response[0]=false;
if(Dependent)
{
//Negateremaininganswers.
_response[1]=false;
_response[2]=false;
}
15.接下来,在AffirmQ1事件处理程序中添加下面的代码:
//Affirmanswer.
_response[0]=true;
16.你现在就已为第一个问题的提问添加了对应的工作流组成部分,但是这还有两个问题。
对于第二个问题,重复步骤3至步骤8来新添加一个IfElse活动添加到工作流中,把和问题1相关的地方用问题2替换掉,例如插入的事件处理程序就应该是AskQuestion2、NegateQ2和AffirmQ2。
工作流视图设计器的界面现在如下所示:
17.现在找到AskQuestion2事件处理程序并添加下面的代码:
if(_response[0]==false&&Dependent)
{
//Noneedtoask!
e.Result=false;
}
else
{
//Askthequestion!
DialogResultresult=MessageBox.Show(Questions[1],"Questioner:
",
MessageBoxButtons.YesNo,MessageBoxIcon.Question);
e.Result=(result==DialogResult.Yes);
} 18.对于NegateQ2事件出现程序,添加下面的代码:
//Negateanswer
_response[1]=false;
if(Dependent)
{
//Negateremaininganswer
_response[2]=false;
}
19.对于AffirmQ2事件处理程序,添加下面的代码:
//Affirmanswer.
_response[1]=true;
20.在一次重复步骤3至步骤8,添加第三个问题,把和问题1相关的内容替换掉(方法和添加第二个问题时一样)。
此时,工作流视图设计器的界面如下所示:
21.找到AskQuestion3事件处理程序,插入下面的代码:
if(_response[1]==false&&Dependent)
{
//Noneedtoask!
e.Result=false;
}
else
{
//Askthequestion!
DialogResultresult=MessageBox.Show(Questions[2],"Questioner:
",
MessageBoxButtons.YesNo,MessageBoxIcon.Question);
e.Result=(result==DialogResult.Yes);
}
22.对于NegateQ3事件处理程序,添加下面的代码:
//Negateanswer.
_response[2]=false;
23.对于AffirmQ3事件处理程序则添加下面的代码:
//Affirmanswer
_response[2]=true;
24.现在回到工作流视图设计器。
你会在工具箱中找到一个名称为SendResponseDataToHost的自定义活动。
(注意:
假如工具箱中没有这个SendResponseDataToHost活动,则编译该项目再重新看看。
)
25.拖拽一个SendResponseDataToHost活动到你的工作流视图设计器界面上,把它放到第三个IfElse活动(ifElseActivity3)的下边。
26.因为返回的数据是一个简单的Boolean类型的数组,因此这里的处理方式和前一章有点点区别。
和你去添加一个容纳该Boolean类型的数组的依赖属性不同,SendResponseDataToHost活动使用一个字段来容纳该数据,创建该字段的用户界面也就和你在第七章中看到的不同。
在VisualStudio属性面板上选中responses属性,然后点击浏览(...)按钮。
这打开了如下面的Boolean集合编器对话框。
27.点击添加按钮,共重复三次,保留这些默认的False值,然后点击确定按钮。
VisualStudio就为你把包含三个Boolean元素的数组添加进了你的Workflow1.designer.cs文件的代码中。
提示:
在下面的第28步,你将添加一个CodeActivity,用它来把你在第11步添加的_response字段分配到我们刚刚为SendResponseDataToHost创建的Boolean数组中。
但是,你也可直接使用SendResponseDataToHost的一个我们已经创建的response属性(来对它进行访问)。
我选择这样做仅仅是因为(从阐述的角度来说)这样更有意义,这可展示出在涉及到宿主通信活动前该Ifelse活动是怎样添加和工作的。
28.现在我们需要把保存了问题回答结果的数组的值和将要使用这些值的SendResponseDataToHost活动联系起来。
因此,我们现在就拖拽一个Code活动到工作流视图设计器的界面上,把它放到第三个IfElse活动(ifElseActivity3)和SendResponseDataToHost活动(sendResponseDataToHost1)之间。
29.设置该Code活动的ExecuteCode属性为CopyResponse,然后按下回车键。
30.在VisualStudio插入的CopyResponse事件处理程序中添加下面的代码:
//Assignoutgoingdata.
sendResponseDataToHost1.responses=_response;
31.编译并运行该应用程序。
改变问题的Dependency属性,看看在回答这些问题时,作出否定的回答其结果一样吗?