WF4.0基础篇学习笔记完整_第1页
WF4.0基础篇学习笔记完整_第2页
WF4.0基础篇学习笔记完整_第3页
WF4.0基础篇学习笔记完整_第4页
WF4.0基础篇学习笔记完整_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

WF4.0基础篇学习笔记WF4.0基础篇学习笔记一开始使用WF创建一个新的“工作流控制台应用程序”包含两部分:用于描述流程结构的一个XAML文件调用流程的宿主程序XAML流程结构描述文件<Activity……x:Class=”WorkflowConsoleApplication1.Workflow1”……><WriteLine……Text=”HelloWorld!”/></Activity>WF4.0的流程是由一组活动组成的,当流程运行时,流程内的活动按一定的顺序依次执行。其中<Activity></Activity>是这个流程的根活动。<WriteLine/>是WF4.0的一个内置活动,其功能就是在屏幕打印Text属性的内容。x:Class=”WorkflowConsoleApplication1.Workflow1”则是将XAML文件编译成.NET类时所对应的类名。宿主程序WorkflowInvoker.Invoke(newWorkflow1());其中,WorkflowInvoker是一个用于调用工作流的功能类,可以使用该类的Invoke静态方法调用流程。Invoke(newWorkflow1())所使用的类就是XAML文件中x:Class=”WorkflowConsoleApplication1.Workflow1”所定义的类名。二Activity介绍及WriteLineActivity的使用活动(Activity):工作流中的内容是一个活动,包括工作流本身。工作流是特殊类型的活动,它一般允许在其中定义其他活动,这称为复合活动。活动是一个最终派生自Activity抽象类的类。类层次结构比Worknow3.x的定义更深,主要类如下图所示:Activity类是所有工作流活动的根,一般从第二层派生自定义活动。要创建一个简单的活动,如上面提到的WriteLine活动,应从CodeActivity中派生,因为这个类有足够的功能可以输出数据行。执行并返回某种形式的结果的活动应派生自ActivityWithResult类——注意这里最好使用泛型类Activity<TResult>,因为它提供了一个强类型化的Result属性。为了让活动执行某个操作,一般应重写Execute()方法,它根据所选择的基类有许多不同的签名,这些签名如下表所示。基类Execute()方法AsyncCodeActivityprotectedabstractIAsyncResultBeginExecute(AsyncCodeActivityContextcontext,AsyncCallbackcallback,Objectstate)protectedabstractvoidEndExecute(AsyncCodeActivityContextcontext,IAsyncResultresult)CodeActivityprotectedabstractvoidExecute(CodeActivityContextcontext)NativeActivityprotectedabstractvoidExecute(NativeActivityContextcontext)AsyncCodeActivity<TResult>protectedabstractIAsyncResultBeginExecute(AsyncCodeActivityContextcontext,AsyncCallbackcallback,Objectstate)protectedabstractTResultEndExecute(AsyncCodeActivityContextcontext,IAsyncResultresult)CodeActivity<TResult>protectedabstractTResultExecute(CodeActivityContextcontext)NativeActivity<TResult>protectedabstractvoidExecute(NativeActivityContextcontext)注意,传送给Execute()方法的参数不同,因为它使用了特定于类型的执行上下文参数。在Workflow3.x中,只使用了一个ActivityExecutionContext类,而在Workflow4中,可以为不同类别的活动使用不同的上下文。主要区别是,与NativeActivityContext相比,CodeActivityContext与派生的AsyncCodeActivityContext的功能有限。这说明,派生自CodeActivity和AsyncCodeActivity的活动可以执行的操作远远少于它们的容器。例如,前面提到的WriteLine活动只需写入控制台,因此,它不需要访问其运行库环境。更复杂的活动需要调度其他子活动,或与其他系统通信,此时就需要从NativeActivity中派生,以访问完整的运行库。WF提供了许多标准活动,下面几节将介绍其中一些活动的示例和使用这些活动的场合。Workflow4使用3个主要的程序集:System.Activities.dll、System.Activities.Core.Presentation.dll和System.Activities.Presentation.dllWriteLine:将指定的字符串写入指定TextWriter对象。类名:System.Activities.Statements.WriteLine程序集:System.Activities(在System.Activities.dll中) 语法:[ContentPropertyAttribute("Text")]publicsealedclassWriteLine:CodeActivity 属性:Text属性:要写入的文本。语法:publicInArgument<string>Text{get;set;}TextWriter属性:要向其中写入Text的TextWriter。语法:publicInArgument<TextWriter>TextWriter{get;set;}三流程实例WorkflowApplication与设计WF程序的基本原则WorkflowInvoker类是Workflow4.0新增的,它允许同步调用工作流,WorkflowInvoker类的同步功能非常适用于运行短时间的工作流,以响应某些UI动作——可以使用工作流启用或禁用UI的某些元素。尽管WorkflowInvoker类对于同步执行工作流很有用,但我们可能需要长时间运行的工作流,它们可以持久化到数据库中,在将来的某个时刻需要提取出来。此时应使用WorkflowApplication类。WorkflowApplication类为单个工作流实例提供宿主。它是由工作流运行时管理的实际工作流实例的代理。WorkflowApplication的用户可以通过调用WorkflowApplication对象中的适当方法,指示工作流运行时在工作流实例上执行操作。如果请求的操作无效,则引发异常。使用WorkflowApplication,可以执行以下任务:●创建新的工作流实例,或从实例存储区中加载工作流实例。●提供扩展以供工作流实例内的活动使用。●控制工作流实例的执行。●恢复由工作流实例内的活动创建的书签。●保留或卸载工作流实例。●接收工作流实例生命周期事件通知。四顺序容器Sequence与CodeActivitySequence:按顺序执行所包含的活动类名:System.Activities.Statements.Sequence程序集:System.Activities(在System.Activities.dll中)语法:[ContentPropertyAttribute("Activities")]publicsealedclassSequence:NativeActivity属性:Activities属性:要按顺序执行的包含的活动的集合。语法:publicCollection<Activity>Activities{get;}Variables属性:包含的变量的集合。语法:publicCollection<Variable>Variables{get;}在WF中,任意从Activity派生的类都可以实例化运行。而用VS2010自带的模板所创建的流程是以System.Activities.Activity为根创建的,这时,在设计器中只能向设计容器中添加一个活动,当然流程在很多时候是具有多个节点的,为了解决这个问题,我们可以向设计器中的Activity根中添加一个顺序容器Sequence,在顺序容器Sequence中,可以添加多个活动,活动在流程运行时按其在顺序容器Sequence中的上下顺序依次执行。WF4.0提供了很多内置活动,但是这些活动并不能完成具体的功能,这就需要我们定义自己的活动。.NETFramework版本4提供了若干用于创建自定义活动的选项,用于创作给定活动的正确方法取决于所需的运行时功能。基本活动类可用的功能Activity将一组系统提供的活动和一组自定义活动组成一个复合活动。CodeActivity通过提供可以重写的Execute方法实现命令性功能。还提供对跟踪、变量以及参数的访问NativeActivity提供CodeActivity的所有功能,另外还可中止活动执行、取消子活动执行、使用书签以及计划活动、活动操作和功能DynamicActivity提供一个类似于DOM的方法,使用该方法可以构造通过IcustomTypeDescriptor与WF设计器和运行时系统交互的活动,从而允许在不定义新类型的情况下创建新活动 ●使用Activity创作活动从Activity派生的活动通过组合其他现有活动来构成功能。这些活动可以是现有的自定义活动,也可以是来自.NETFramework版本4活动库的活动。组合这些活动是创建自定义功能的最基本方法。使用可视化设计环境创作工作流时这种方法最常用。 ●使用CodeActivity创作活动从CodeActivity派生的活动可以通过用自定义的命令性代码重写Execute方法来实现命令性功能。活动由运行时执行时将执行该自定义代码。尽管使用这种方法创建的活动可以访问自定义功能,但是它们无法访问运行时的所有功能,如对执行环境的完全访问或对Cancel或Abort方法的支持。执行CodeActivity时,它可以访问简化版本的执行环境(通过CodeActivityContext类)。使用CodeActivity创建的活动可以访问参数和变量解析、扩展以及跟踪。可以使用AsyncCodeActivity进行异步活动计划。 ●使用NativeActivity创作活动从NativeActivity派生的活动,与从CodeActivity派生的活动一样,可通过重写Execute来创建命令性功能,除此之外还可以通过传递给Execute方法的NativeActivityContext访问工作流运行时的所有功能。此上下文支持安排和取消子活动、执行ActivityAction和ActivityFunc对象、取消和中止执行、访问执行属性和扩展以及书签(用于继续已暂停工作流的句柄)。 ●使用DynamicActivity创作活动与其他三种活动类型不同,不会通过从DynamicActivity(该类是密封的)派生新类型来创建新功能,而是通过使用活动文档对象模型(DOM)将功能组合到Properties和Implementation属性中。 ●创作返回结果的活动很多活动必须在其执行之后返回结果。尽管可以在活动上始终定义一个自定义OutArgument来实现此目的,但是建议改用Activity或者从CodeActivity或NativeActivity派生。这些基类中的每个类都具有一个名为Result的OutArgument,您的活动可以使用它作为其返回值。CodeActivity:一种抽象类,用于创建具有强制行为(该行为是使用Execute(CodeActivityContext)方法定义的,利用该方法可以访问变量以及参数解析和扩展)的自定义活动。类名:System.Activities.CodeActivity程序集:System.Activities(在System.Activities.dll中)功能说明:一个抽象类,继承该类后,需要override该类的Execute方法,用于编写自定义的功能代码。在WF中,变量表示数据的存储区,参数表示流入和流出活动的数据。活动拥有一组参数,这些参数构成活动的签名。此外,活动可以维护一个变量列表,在工作流设计期间,开发人员可在该列表中添加或移除变量。使用可返回值的表达式可以绑定参数。五数据的传递(Variable变量)变量是数据的存储位置。变量被声明为工作流定义的一部分。变量在运行时获取值,并将这些值存储为工作流实例状态的一部分。变量定义指定了变量的类型,如果需要,还可指定变量的名称。Variable:可以从中派生工作流数据成员支持类Variable<T>的抽象基类。类名:System.Activities.Variable程序集:System.Activities(在System.Activities.dll中)语法:publicabstractclassVariable:LocationReference属性:Name属性:获取或设置Variable的名称。语法:publicstringName{get;set;}Modifiers属性:获取或设置此Variable的VariableModifiers值。 语法:publicVariableModifiersModifiers{get;set;}代码创建Variable示例:Variable<string>var=newVariable<string>{Default="HelloWorld.",Modifiers=VariableModifiers.ReadOnly};注意:只有具备Variables属性的Activity才可以定义变量。定义了变量的活动的内部活动是可以访问该变量的,它的外部活动不能访问该变量。变量的作用域:变量在运行时的生存期与声明该变量的活动的生存期相同。活动完成后,其变量将被清除,并且无法再引用。Assign:为工作流级的变量赋值。类名:System.Activities.Statements.Assign程序集:System.Activities(在System.Activities.dll中)语法:publicsealedclassAssign:CodeActivity属性:To属性:指定活动将为其分配活动的Value值的Argument。 语法:[RequiredArgumentAttribute] publicOutArgumentTo{get;set;}Value属性:指定分配的值。 语法:[RequiredArgumentAttribute]publicInArgumentValue{get;set;}六数据的传递(Arguments参数)活动作者使用参数来定义数据流入流出活动的方式。在同一个流程内,所有活动共享一组参数。每个参数都有特定的方向:In、Out、或InOut。工作流运行时对数据流入流出活动的时间有以下保证:●活动开始执行时,将计算其所有输入和输入/输出参数的值。例如,不管何时调用Get,返回值都为调用Execute之前运行时所计算的值。●调用Set时,运行时将立即设置值。●可根据需要指定参数的EvaluationOrder。EvaluationOrder是一个从零开始的值,用于指定参数的计算顺序。默认情况下,参数的计算顺序未指定且等于UnspecifiedEvaluationOrder值。将EvaluationOrder设置为一个大于或等于零的值,以便为此参数指定一个计算顺序。WF以指定的计算顺序按升序计算参数。请注意,未指定计算顺序的参数将先于指定计算顺序的参数计算。活动作者可使用强类型机制来公开该活动的参数。实现方法是声明InArgument、OutArgument和InOutArgument类型的属性。这允许活动作者建立有关流入流出活动的数据的特定协定。InArument<T>:表示数据流入活动的绑定终端。类名:System.Activities.InArgument<T>程序集:System.Activities(在System.Activities.dll中)语法:[ContentPropertyAttribute("Expression”)] [TypeConverterAttribute(typeof(InArgumentConverter))]publicsealedclassInArgument<T>:InArgument 使用说明:可以用VS设计器在xaml中定义In参数在xaml中定义的In参数,可以在该xaml中被其他Activity用表达式绑定可以用code方式在codeActivity中定义In参数可以在属性框中,将codeActivity中定义的In参数绑定到参数或变量,可以用表达式方式赋值运行时,可以用启动参数的方式对In参数赋值(xaml和code方式一样)In参数不能在实例的OnCompleted事件中用WorkflowApplicationCompletedEventArgs.Outputs得到。可以使用Assign为In参数赋值示例:在xaml形式的流程图中使用In参数先在流程图TestInXamlWorkflow.xaml文件中定义3个double型的In参数v1,v2,v3;启动时为v1,v2赋值在流程内部用Assign为v3赋值v1+v2用WriteLine打印v3的值。下面是使用WorkflowApplication创建传入参数的实例代码:System.Collections.Generic.Dictionary<string,object>dic=newSystem.Collections.Generic.Dictionary<string,object>();dic.Add(“v1”,12.34);//前一个值是参数名,必须与实际参数名相同,后面是传入值。dic.Add(“v2”,56.78);WorkflowApplicationmyIn=newWorkflowApplication(newTestInXamlWorkflow(),dic);myIn.Run();在自定义代码活动中使用In参数自定义活动代码如下:publicsealedclassTestInCodeActivity:CodeActivity{publicInArgument<string>Text{get;set;}protectedoverridevoidExecute(CodeActivityContextcontext){stringstr1=context.GetValue(this.Text);//得到Text参数值的第一种方式stringstr2=Text.Get(context);//得到Text参数值的第二种方式Console.WriteLine(str1);Console.WriteLine(str2);}}创建带参数传入的WorkflowApplication实例代码如下:System.Collections.Generic.Dictionary<string,object>dic=newSystem.Collections.Generic.Dictionary<string,object>();dic.Add(“Text”,”Victor”);WorkflowApplicationmyIn=newWorkflowApplication(newTestInXamlWorkflow(),dic);myIn.Run();在Xaml形式的流程图中使用带参数的自定义活动,需要在流程图中添加参数并与自定义活动的参数绑定在一起。OutArument<T>:表示数据流出活动的绑定终端。类名:System.Activities.OutArgument<T>程序集:System.Activities(在System.Activities.dll中)语法:[ContentPropertyAttribute("Expression”)] [TypeConverterAttribute(typeof(OutArgumentConverter))]publicsealedclassOutArgument<T>:OutArgument 使用说明:可以用VS设计器在xaml中定义Out参数在xaml中定义的Out参数,可以在该xaml中被其他Activity用表达式绑定可以用code方式在codeActivity中定义Out参数可以在属性框中,将codeActivity中定义的Out参数绑定到参数或变量,不能直接对Out参数赋值运行时,不能用启动参数的方式对Out参数赋值(xaml和code方式都不能)Out参数可以在实例的OnCompleted事件中用WorkflowApplicationCompletedEventArgs.Outputs得到。可以使用Assign为Out参数赋值示例:在xaml形式的流程图中使用Out参数先在流程图TestOutXamlWorkflow.xaml文件中定义2个double型的In参数v1,v2,和定义一个double型的Out参数v3;启动时为v1,v2赋值在流程内部用Assign为v3赋予v1+v2在completed中打印v3的值启动时赋值的代码如下:System.Collections.Generic.Dictionary<string,object>dic=newSystem.Collections.Generic.Dictionary<string,object>();dic.Add(“v1”,12.34);dic.Add(“v2”,56.78);WorkflowApplicationmyOut=newWorkflowApplication(newTestOutXamlWorkflow(),dic);myOut.Completed=completed;myOut.Run();staticvoidcompleted(WorkflowApplicationCompletedEventArgse){Console.WriteLine(e.Outputs[“v3”].ToString());}在自定义代码活动中使用Out参数自定义活动代码如下:publicsealedclassTestOutCodeActivity:CodeActivity{publicOutArgument<string>Text{get;set;}protectedoverridevoidExecute(CodeActivityContextcontext){stringstr1=context.GetValue(this.Text);//得到Text参数值的第一种方式context.SetValue(Text,“ABC”+str1);//设置Text参数值的第一种方式stringstr2=Text.Get(context);//得到Text参数值的第二种方式Text.Set(context,“ABC”+str2);//设置Text参数值的第二种方式Console.WriteLine(Text.Get(context));}}创建WorkflowApplication实例启动流程,代码如下:WorkflowApplicationmyOut=newWorkflowApplication(newTestOutXamlWorkflow());myOut.Run();在Xaml形式的流程图中使用带参数的自定义活动,需要在流程图中添加参数或变量并与自定义活动的参数绑定在一起。InOutArument<T>:表示数据流入和流出活动的绑定终端。类名:System.Activities.InOutArgument<T>程序集:System.Activities(在System.Activities.dll中)语法:[ContentPropertyAttribute("Expression”)] [TypeConverterAttribute(typeof(InOutArgumentConverter))]publicsealedclassInOutArgument<T>:InOutArgument 使用说明:可以用VS设计器在xaml中定义In/Out参数在xaml中定义的In/Out参数,可以在该xaml中被其他Activity用表达式绑定可以用code方式在codeActivity中定义In/Out参数可以在属性框中,将codeActivity中定义的In/Out参数绑定到参数或变量,不能直接对In/Out参数赋值运行时,可以用启动参数的方式对In/Out参数赋值(xaml和code方式都可以)In/Out参数可以在实例的OnCompleted事件中用WorkflowApplicationCompletedEventArgs.Outputs得到。可以使用Assign为In/Out参数赋值示例:在xaml形式的流程图中使用In/Out参数先在流程图TestInOutXamlWorkflow.xaml文件中定义3个string型的In/Out参数v1,v2,v3;启动时为v1,v2,v3赋值在流程内部用Assign为v3赋予v1+v2+v3在completed中打印v3的值启动流程代码:System.Collections.Generic.Dictionary<string,object>dic=newSystem.Collections.Generic.Dictionary<string,object>();dic.Add(“v1”,“AA”);dic.Add(“v2”,“BB”);dic.Add(“v3”,“CC”);WorkflowApplicationmyInOut=newWorkflowApplication(newTestInOutXamlWorkflow(),dic);myInOut.Completed=completed;myInOut.Run();staticvoidcompleted(WorkflowApplicationCompletedEventArgse){Console.WriteLine(e.Outputs[“v3”].ToString());}在自定义代码活动中使用In/Out参数自定义活动代码如下:publicsealedclassTestInOutCodeActivity:CodeActivity{publicInOutArgument<string>Text{get;set;}protectedoverridevoidExecute(CodeActivityContextcontext){stringstr=context.GetValue(this.Text);context.SetValue(Text,“你好:”+str);Console.WriteLine(context.GetValue(this.Text));}}启动代码如下:System.Collections.Generic.Dictionary<string,object>dic=newSystem.Collections.Generic.Dictionary<string,object>();dic.Add(“Text”,”Victor”);WorkflowApplicationmyInOut=newWorkflowApplication(newTestInOutCodeActivity(),dic);myInOut.Run();在Xaml形式的流程图中使用带参数的自定义活动,需要在流程图中添加参数或变量并与自定义活动的参数绑定在一起。返回单个值的活动可从Activity、NativeActivity或CodeActivity派生。这些活动拥有定义完善的名为Result的OutArgument,它包含活动的返回值。七数据的传递(变量与参数的使用)In参数:与该参数关联的变量值可传入内部;内部修改参数时,关联的变量不会更改。示例:定义一个自定义活动,代码如下:publicsealedclassTestInChangeCodeActivity:CodeActivity{publicInArgument<string>Text{get;set;}protectedoverridevoidExecute(CodeActivityContextcontext){stringstr1=context.GetValue(this.Text);//得到从外部变量传入的值Console.WriteLine(“传入值为:{0}”,str1);Context.SetValue(Text,”BB”);//修改参数的值stringstr2=context.GetValue(this.Text);Console.WriteLine(“内部修改为:{0}”,str2);}}在xaml工作流中创建了一个变量,并赋值为“AA”,然后将上面自定义活动的Text参数和变量绑定,最后打印出变量的值。结果如下:Out参数:与该参数关联的变量值无法传入内部;内部修改参数时,关联的变量也会更改。示例:将上面[In参数]示例中自定义活动中的参数类型修改为OutArgument<string>,其他的不变。结果如下:In/Out参数:与该参数关联的变量值可以传入内部;内部修改参数时,关联的变量也会更改。示例:将上面[In参数]示例中自定义活动中的参数类型修改为InOutArgument<string>,其他的不变。结果如下:八控制流ActivityIf:建立If-Then-Else条件的模型。类名:System.Activities.Statements.If程序集:System.Activities(在System.Activities.dll中) 语法:publicsealedclassIf:NativeActivity 属性:Condition属性:用于确定要执行哪个子活动的条件。Then活动在条件解析为true的情况下执行。Else活动在条件解析为false的情况下执行。语法:[RequiredArgumentAttribute]publicInArgument<bool>Condition{get;set;}Then属性:要在活动的Condition解析为true的情况下执行的活动。语法:publicActivityThen{get;set;}Else属性:要在活动的Condition解析为false的情况下执行的活动。语法:publicActivityElse{get;set;}Switch<T>:基于给定表达式(其类型在此对象的类别说明符中指定)的值,从要执行的多个活动中选择一个活动。类名:System.Activities.Statements.Switch<T>程序集:System.Activities(在System.Activities.dll中) 语法:[ContentPropertyAttribute("Cases”)]publicsealedclassSwitch<T>:NativeActivity 属性:Expression属性:获取要与Cases()集合中的键进行比较的对象。语法:[RequiredArgumentAttribute]publicInArgument<T>Expression{get;set;}Cases属性:表示可能执行路径的字典。每个条目都包含一个键以及一个将在表达式结果与该键匹配时执行的活动。语法:publicIDictionary<T,Activity>Cases{get;}Default属性:表示在Cases()集合中没有条目键与Expression()属性匹配的情况下执行的活动。语法:publicActivityDefault{get;set;}While:在条件的计算结果为true时执行包含的工作流元素。类名:System.Activities.Statements.While程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Body")]publicsealedclassWhile:NativeActivity 属性:Condition属性:要在While循环的每次迭代之前执行的Activity<Tresult>。语法:publicActivity<bool>Condition{get;set;}Body属性:要在While循环中执行的Activity。语法:publicActivityBody{get;set;}Variables属性:与While活动关联的Variable对象的集合。语法:publicCollection<Variable>Variables{get;}DoWhile:一个循环活动,该活动将执行包含的活动至少一次,直至条件不再为true为止。类名:System.Activities.Statements.DoWhile程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Body")]publicsealedclassDoWhile:NativeActivity 属性:Condition属性:在循环结尾进行检查以确定是否再次执行循环的[T:System.Activities.Activity]。语法:publicActivity<bool>Condition{get;set;}Body属性:要随每次迭代一起执行的子活动。语法:publicActivityBody{get;set;}Variables属性:与DoWhile活动关联的Variable对象的集合。语法:publicCollection<Variable>Variables{get;}ForEach<T>:为Values集合中提供的每个值执行活动操作一次。类名:System.Activities.Statements.ForEach<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Body")]publicsealedclassForEach<T>:NativeActivity 属性:Body属性:要为Values集合中的每一项执行的ActivityAction。语法:publicActivityAction<T>Body{get;set;}Values属性:活动的输入集合,用于执行Body活动操作。语法:[RequiredArgumentAttribute]publicInArgument<IEnumerable<T>>Values{get;set;}九控制流Activity(二)Parallel:一个以异步方式同时执行所有子活动的活动。类名:System.Activities.Statements.Parallel程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Branches")]publicsealedclassParallel:NativeActivity 属性:CompletionCondition属性:在任何分支完成后计算。语法:publicActivity<bool>CompletionCondition{get;set;}说明:如果此属性的计算结果为true,则会取消Branches集合中其他安排的元素。如果未设置此属性,则Branches集合中的所有Activity对象都将执行,直至完成为止。Branches属性:要并行执行的子元素。语法:publicCollection<Activity>Branches{get;}Variables属性:包含的变量的集合。语法:publicCollection<Variable>Variables{get;}说明:Parallel活动的工作方式为:在启动时同时安排其Branches集合中的每个Activity。该活动将在所有其Branches均完成或其CompletionCondition属性的计算结果为true时完成。尽管所有Activity对象均异步运行,但它们不会在单独的线程上运行,因此每个连续的活动将只会在以前安排的活动完成或进入空闲状态时执行。如果此活动没有任何子活动进入空闲状态,则此活动将采用与Sequence活动相同的方式执行。Parallel中可以定义变量Parallel会并行执行Branches集合内的所有Activity当CompletionCondition属性为true时,并行容器完成,其他没有执行完成的分支就不再执行了(包括执行一半的分支)示例:基本使用1、在流程中添加[WriteLine]打印当前时间2、添加[Parallel],并添加两个分支第一个分支添加[Delay]延时10秒,添加[WriteLine]打印当"A"第二个分支添加[Delay]延时15秒,添加[WriteLine]打印当"B"3、在流程中添加[WriteLine]打印当前时间预期:两次的系统时间差为15秒表示为并行,两次的系统时间差为25秒表示为串行结果:CompletionCondition使用1、在流程中添加bool型变量[myVariable],默认值False2、添加[Parallel],并添加三个分支第一个分支:添加[WriteLine]打印当"A1";添加[Delay]延时10秒;添加[WriteLine]打印当"A2"第二个分支:添加[WriteLine]打印当"B1";添加[Delay]延时15秒;添加[WriteLine]打印当"B2";添加[Assign]为变量[myVariable]赋值True第三个分支:添加[WriteLine]打印当"C1";添加[Delay]延时20秒;添加[WriteLine]打印当"C2"预期:[Assign]为变量[myVariable]赋值True后,容器结束,因此会依次看到[A1,B1,C1,A2,B2],但看不到[C2]结果:Pick:提供基于事件的控制流建模。类名:System.Activities.Statements.Pick程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Branches")]publicsealedclassPick:NativeActivity 属性:Branches属性:PickBranch对象的集合,Pick活动可能会基于传入的事件执行其中的一个活动。语法:publicCollection<PickBranch>Branches{get;}说明: 此活动的行为与Switch的类似之处在于:它只执行若干活动中的一个活动来响应事件。选择执行的活动由从一组事件中选择的一个事件定义。PickBranch:Pick活动内的可能执行路径。类名:System.Activities.Statements.PickBranch程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Action")]publicsealedclassPickBranch 属性:Action属性:要在已触发执行此分支的情况下执行的Activity。语法:publicActivityAction{get;set;}DisplayName属性:在活动设计器中显示的此分支的名称。语法:publicstringDisplayName{get;set;}Trigger属性:其完成激活此pick分支的活动。语法:publicActivityTrigger{get;set;}Variables属性:与此活动关联的用户定义变量的集合。语法:publicCollection<Variable>Variables{get;}说明: PickBranch包含Trigger和Action。开始执行Pick元素时,会安排所有PickBranch元素中的所有触发器活动。在第一个活动完成之后,安排其相应的操作活动,并且取消所有其他触发器活动。Pick和PickBranch的一些说明:●Pick触发容器,提供了基于事件的控制流。Branches集合是触发容器的分支集合,只能添加PickBranch●Pick触发容器中可以定义变量●PickBranch只可添加到Pick中,PickBranch.Trigger只能放入触发类Activity;PickBranch.Action当PickBranch.Trigger被触发时,所要执行的●只要有一个PickBranch的Trigger被触发,其他PickBranch就不会被触发了●即使在被执行的PickBranch还没完成时,其他PickBranch也不会被触发示例:基本使用1、在工作流中添加[WriteLine],打印系统时间2、在工作流中添加[Pick],添加三个[PickBranch]第一个分支:[Trigger]添加[Delay]延时15秒[Action]添加[WriteLine]打印当"A"第二个分支:[Trigger]添加[Delay]延时10秒[Action]添加[WriteLine]打印当"B1"添加[Delay]延时15秒添加[WriteLine]打印当"B2"第三个分支:[Trigger]添加[Delay]延时20秒[Action]添加[WriteLine]打印当"C"预期:只有第二个分支会被执行结果:ParallelForEach<T>:枚举集合元素并对集合中的每个元素并行执行嵌入语句。类名:System.Activities.Statements.ParallelForEach<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Body")]publicsealedclassParallelForEach<T>:NativeActivity 属性:CompletionCondition属性:在每个迭代完成后计算。语法:publicActivity<bool>CompletionCondition{get;set;}说明:如果其计算结果为true,则取消已安排的挂起的迭代。如果未设置此属性,则所有安排的语句都将执行,直至完成为止。Body属性:为Values集合中包含的每个值执行一次的ActivityAction。语法:publicActivityAction<T>Body{get;set;}Values属性:值的集合,用作Body中所包含活动的每个迭代的参数。语法:[RequiredArgumentAttribute]publicInArgument<IEnumerable<T>>Values{get;set;}说明:嵌入的语句将一起安排并异步运行,但它们不会在单独的线程上运行,因此每个连续的活动将只会在以前安排的活动完成或进入空闲状态时执行。如果此活动没有任何子活动进入空闲状态,则此活动将采用与ForEach<T>活动相同的方式执行。 示例: ①基本使用1、创建一codeactivity名为CollectionCodeActivity,具有Out参数,类型为List<string>的参数myOutCollection2、在流程中添加List<string>变量myCollection3、在流程中添加CollectionCodeActivity,将CollectionCodeActivity.myOutCollection参数绑定到myCollection变量4、在流程中添加ForEach<T>,TypeArgument属性指定string,Values属性绑定到myCollection变量,在Body中添加WriteLine,打印item自定义活动代码如下:publicsealedclassCollectionCodeActivity:CodeActivity{publicOutArgument<List<string>>myOutCollection{get;set;}protectedoverridevoidExecute(CodeActivityContextcontext){List<string>list=newList<string>();list.Add(“A”);list.Add(“B”);list.Add(“C”);context.SetValue(this.myOutCollection,list);}}结果:十Collection集合操作AddToCollection<T>:向指定集合中添加项。类名:System.Activities.Statements.AddToCollection<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Collection")]publicsealedclassAddToCollection<T>:CodeActivity 属性:Collection属性:接收新项的集合。语法:[RequiredArgumentAttribute]publicInArgument<ICollection<T>>Collection{get;set;}Item属性:要添加到指定集合中的项。语法:[RequiredArgumentAttribute]publicInArgument<T>Item{get;set;}RemoveFromCollection<T>:从指定集合中移除项。类名:System.Activities.Statements.RemoveFromCollection<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Collection")]publicsealedclassRemoveFromCollection<T>:CodeActivity<bool> 属性:Collection属性:要从中移除Item的集合。语法:[RequiredArgumentAttribute]publicInArgument<ICollection<T>>Collection{get;set;}Item属性:要从指定的Collection中移除的项。语法:[RequiredArgumentAttribute]publicInArgument<T>Item{get;set;}Result属性:表示操作结果,如果操作成功返回True,不成功返回False说明:如果集合中的有两个相同的项,只移除第一个。ClearCollection<T>:从指定集合中移除项。类名:System.Activities.Statements.ClearCollection<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Collection")]publicsealedclassClearCollection<T>:CodeActivity 属性:Collection属性:要清除其内容的集合。语法:[RequiredArgumentAttribute]publicInArgument<ICollection<T>>Collection{get;set;}ExistsInCollection<T>:指示给定项是否存在于给定集合中。类名:System.Activities.Statements.ExistsInCollection<T>程序集:System.Activities(在System.Activities.dll中) 语法:ContentPropertyAttribute("Collection")]publicsealedclassExistsInCollection<T>:CodeActivity<bool> 属性:Collection属性:要进行搜索以查找指定元素的集合。语法:[RequiredArgumentAttribute]publicInArgument<ICollection<T>>Collection{get;set;}Item属性:要在指定集合中搜索的项。语法:[RequiredArgumentAttribute]publicInArgument<T>Item{get;set;}Result属性:表示查找结果,如果存在成功返回True,不存在返回False十一Exception异常与TerminateWorkflow结束异常WF为在工作流中处理运行时错误条件提供了多个不同机制。工作流可以结合使用异常处理程序、事务以及补偿来妥善处理错误条件并从中恢复。工作流可以使用TryCatch活动处理工作流执行期间引发的异常。可以对这些异常进行处理,或者使用Rethrow活动重新引发异常。Finally节中的活动在Try节或Catches节完成时执行。工作流还可以使用WorkflowInstance的OnUnhandledException事件处理程序处理未由TryCatch活动处理的异常。异常的原因:在工作流中,异常可能通过下列方式生成:●TransactionScopeActivity中的事务超时。●工作流通过使用Throw活动引发的显式异常。●某个活动引发的.NETFramework4异常。●外部代码引发的异常,例如工作流中使用的库、组件或服务。WF流程结束方式:WF实例如果在运行过程中没有出现问题,ActivityInstanceState(实例状态)会由Executing(执行中)变为Closed(关闭)。如果流程被调用Terminate方法遇到TerminateWorkflow活动产生异常时没有用WorkflowApplication.OnUnhandledException产生异常时指定UnhandledExceptionAction.TerminateActivityInstanceState(实例状态)会由Executing(执行中)变为faulted(有问题)。如果流程被调用Canceled方法产生异常时指定UnhandledExceptionAction.CanceledActivityInstanceState(实例状态)会由Executing(执行中)变为Canceled(取消)。如果流程被调用Aborted方法产生异常时指定UnhandledExceptionAction.Aborted流程会运行失败,并触出发实例的Aborted运行失败的流程无ActivityInstanceState(实例状态)。ActivityInstanceState(实例状态)的Closed(关闭),faulted(有问题),Canceled(取消)都表示流程结束,并触出发实例的Completed。流程Aborted(中止),流程会即时消失,触出发实例的Aborted,不会触出发实例的Completed。WorkflowApplication的几个属性:●Aborted属性:获取或设置中止工作流实例时调用的Action<T>。语法:publicAction<WorkflowApplicationAbortedEventArgs>Aborted{get;set;}属性值类型:SystemAction<WorkflowApplicationAbortedEventArgs>终止工作流实例时调用的操作。●Completed属性:获取或设置工作流实例完成时调用的Action<T>。语法:publicAction<WorkflowApplicationCompletedEventArgs>Completed{get;set;}属性值类型:SystemAction<WorkflowApplicationCompletedEventArgs>工作流实例完成时调用的操作。●Idel属性:获取或设置当前工作流实例进入空闲状态时调用的Action<>。语法:publicAction<WorkflowApplicationIdleEventArgs>Idle{get;set;}属性值类型:SystemAction<WorkflowApplicationIdleEventArgs>工作流实例进入空闲状态时执行的操作。●OnUnhandledException属性:获取或设置当前工作流实例遇到未处理的异常时调用的Func<T,Tresult>。语法:publicFunc<WorkflowApplicationUnhandledExceptionEventArgs,UnhandledExceptionAction>OnUnhandledException{get;set;}属性值类型:SystemFunc<WorkflowApplicationUnhandledExceptionEventArgs,UnhandledExceptionAction>工作流实例遇到未处理的异常时调用的委托。●PersistableIdle属性:获取或设置当前工作流实例处于空闲状态并可被保留时调用的ActivityFunc。语法:publicFunc<WorkflowApplicationIdleEventArgs,PersistableIdleAction>PersistableIdle{get;set;}属性值类型:SystemFunc<WorkflowApplicationIdleEventArgs,PersistableIdleAction>当前工作流实例处于空闲状态并可被保留时调用的ActivityFunc。●Unloaded属性:获取或设置卸载当前工作流时调用的Action<T>。语法:publicAction<WorkflowApplicationEventArgs>Unloaded{get;set;}属性值类型:SystemAction<WorkflowApplicationEventArgs>卸载工作流实例时调用的操作。使用WorkflowApplication.OnUnhandledException处理Code异常如果异常由某个活动引发并且未经处理,则默认行为是终止该工作流实例。如果存在自定义OnUnhandledException处理程序,则它会重写此默认行为。通过此处理程序,工作流宿主作者能够提供合适的处理操作,例如自定义日志记录、中止工作流、取消工作流或终止工作流。示例:处理Code异常,下面是产生Code异常的Activity的代码:publicsealedclassTestCodeExceptionActivity:CodeActivity{protectedoverridevoidExecute(CodeActivityContextcontext){intv=1–1;doublei=1/v;}}工作流完成时调用的Action代码如下:staticvoidworkflowCompleted(WorkflowApplicationCompletedEventArgse){Console.WriteLine("工作流顺利完成,实例编号:{0},状态:{1}",e.InstanceId,e.CompletionState.ToString());}工作流中止时调用的Action代码如下:staticvoidworkflowAborted(WorkflowApplicationAbortedEventArgse){Console.WriteLine("工作流被中止,实例编号:{0},Reason:{1}",e.InstanceId,e.Reason.Message);}工作流遇到未处理的异常时返回UnhandledExceptionAction.Abort代码如下:staticUnhandledExceptionActionunhandledException_Abort(WorkflowApplicationUnhandledExceptionEventArgse){Console.WriteLine("遇到未处理的异常_Abort:{0}",e.UnhandledException.Message);returnUnhandledExceptionAction.Abort;}工作流遇到未处理的异常时返回UnhandledExceptionAction.Terminate代码如下:staticUnhandledExceptionActionunhandledException_Terminate(WorkflowApplicationUnhandledExceptionEventArgse){Console.WriteLine("遇到未处理的异常_Terminate:{0}",e.UnhandledException.Message);returnUnhandledExceptionAction.Terminate;}不使用UnhandledExceptionAction方式staticvoidExceptionWithoutUnhandledException_None(){WorkflowApplicationmyInstance=newWorkflowApplication(newTestExceptionWithoutUnhandledExceptionWorkflow());myInstance.Completed=newAction<WorkflowApplicationCompletedEventArgs>(workflowCompleted);myInstance.Aborted=newAction<WorkflowApplicationAbortedEventArgs>(workflowAborted);myInstance.Run();}结果:使用UnhandledExceptionAction.Abort方式staticvoidExceptionWithUnhandledException_Abort(){WorkflowApplicationmyInstance=newWorkflowApplication(newTestExceptionWithUnhandledExceptionWorkflow());myInstance.Completed=newAction<WorkflowApplicationCompletedEventArgs>(workflowCompleted);myInstance.Aborted=newAction<WorkflowApplicationAbortedEventArgs>(workflowAborted);myInstance.OnUnhandledException=newFunc<WorkflowApplicationUnhandledExceptionEventArgs,UnhandledExceptionAction>(unhandledException_Abort);myInstance.Run();}结果:使用UnhandledExceptionAction.Terminate方式staticvoidExceptionWithUnhandledException_Terminate(){WorkflowApplicationmyInstance=newWorkflowApplication(newTestExceptionWithUnhandledExceptionWorkflow());myInstance.Completed=newAction<WorkflowApplicationCompletedEventArgs>(workflowCompleted);myInstance.Aborted=newAction<WorkflowApplicationAbortedEventArgs>(workflowAborted);myInstance.OnUnhandledException=newFunc<WorkflowApplicationUnhandledExceptionEventArgs,UnhandledExceptionAction>(unhandledException_Terminate);myInstance.Run();}结果:使用UnhandledExceptionAction.Cancel方式如果异常出现在Cancellation

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论