WF4.0:四种自定义类型活动

     工作流中的活动就像用户自定义的控件,将许多的功能封装起来用。WF4.0中提供了四种可继承的活动类:CodeActivity 、AsyncCodeActivity、Activity、NativeActivity。这几种活动都有自己使用的适合场合,正确的使用这些活动将非常有利。

1、CodeActivity

     WF4.0中的活动是树形结构的,创建叶子活动最简单是方式就是使用CodeActivity ,它的逻辑都放在一个方法:Execute 里面,这个也是四种活动中最简单的一种。这里用一个简单的自定活动HttpGet来说明怎么使用CodeActivity。HttpGet的功能是从网络上抓取数据。

     public   sealed   class  HttpGet : CodeActivity < string >
    {
        
public  InArgument < string >  Uri {  get set ; }

        
protected   override   string  Execute(CodeActivityContext context)
        {
            WebRequest request 
=  HttpWebRequest.Create( this .Uri.Get(context));

            
using  (WebResponse response  =  request.GetResponse())
            {
                
// read everything response.GetResponseStream() as one string
                 using  (StreamReader reader  =   new  StreamReader(response.GetResponseStream()))
                {
                    
return  reader.ReadToEnd();
                }
            }

        }

    }

    public InArgument<string> Uri { get; set; }是工作流中的一个属性,相当于类的属性,不过取它的值与类有点不同,你需要使用:Uri.Get(context))或者context.GetValue(Uri),Execute方法是这个活动的逻辑,特别注意CodeActivityContext context参数,这是WF的上下文,非常有用。

如何使用这个活动:

 HttpGet fetchMsn  =   new  HttpGet
     {
         Uri 
=   " http://www.msn.com "
     };
     
string  msnContent  =  WorkflowInvoker.Invoke < string > (fetchMsn);
     Console.WriteLine(msnC
ontent);

2、AsyncCodeActivity

    AsyncCodeActivity 类似CodeActivity ,只是它是使用了 Begin/EndExecute 取代了CodeActivityExecute 方法。BeginExecute 开始一个异步操作,无需等待它完成,就返回IAsyncResult对象 。当这个操作完成的时候,就执行EndExecute 方法放回结果。HttpGet 能这样实现,请注意CodeActivityContext换成了AsyncCodeActivityContext:

    class  HttpGet : AsyncCodeActivity < string >
    {
        
public  InArgument < string >  Uri {  get set ; }

        
protected   override  IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback,  object  state)
        {
            WebRequest request 
=  HttpWebRequest.Create( this .Uri.Get(context));
            context.UserState 
=  request;
            
return  request.BeginGetResponse(callback, state);            
        }

        
protected   override   string  EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
        {
            WebRequest request 
=  (WebRequest)context.UserState;
            
using  (WebResponse response  =  request.EndGetResponse(result))
            {
                
using  (StreamReader reader  =   new  StreamReader(response.GetResponseStream()))
                {
                    
return  reader.ReadToEnd();
        
        }
            }
        }
    }

3、Activity

    Activity可以以组合的方式定义活动。开发人员可以使用已有活动构建一个活动树来实现这个活动。如果你需要在工作流中完成一些复杂的逻辑,可以使用这种方式。这里用一个flowchart为例:

代码
public   sealed   class  FlowChartActivity : Activity
    {
        
public   string  promoCode {  get set ; }

        
public   int  numKids {  get set ; }

        
public  FlowChartActivity( string  promoCode,  int  numKids)
        {
            
this .promoCode  =  promoCode;
            
this .numKids  =  numKids;
            
base .Implementation  =   new  Func < Activity > (CreateBody);
        }

        Activity CreateBody()
        {
            Variable
< string >  promo  =   new  Variable < string >  { Default  =  promoCode};
            Variable
< int >  numberOfKids  =   new  Variable < int >  { Default  =  numKids };
            Variable
< double >  discount  =   new  Variable < double > ();
            DelegateInArgument
< DivideByZeroException >  ex  =   new  DelegateInArgument < DivideByZeroException > ();

            FlowStep discountNotApplied 
=   new  FlowStep
            {
                Action 
=   new  WriteLine
                {
                    DisplayName 
=   " WriteLine: Discount not applied " ,
                    Text 
=   " Discount not applied "
                },
                Next 
=   null
            };

            FlowStep discountApplied 
=   new  FlowStep
            {
                Action 
=   new  WriteLine
                {
                    DisplayName 
=   " WriteLine: Discount applied " ,
                    Text 
=   " Discount applied  "
                },
                Next 
=   null
            };

            FlowDecision flowDecision 
=   new  FlowDecision
            {
                Condition 
=  ExpressionServices.Convert < bool > ((ctx)  =>  discount.Get(ctx)  >   0 ),
                True 
=  discountApplied,
                False 
=  discountNotApplied
            };

            FlowStep singleStep 
=   new  FlowStep
            {
                Action 
=   new  Assign
                {
                    DisplayName 
=   " discount = 10.0 " ,
                    To 
=   new  OutArgument < double > (discount),
                    Value 
=   new  InArgument < double > ( 10.0 )
                },
                Next 
=  flowDecision
            };

            FlowStep mnkStep 
=   new  FlowStep
            {
                Action 
=   new  Assign
                {
                    DisplayName 
=   " discount = 15.0 " ,
                    To 
=   new  OutArgument < double > (discount),
                    Value 
=   new  InArgument < double > ( 15.0 )
                },
                Next 
=  flowDecision
            };

            FlowStep mwkStep 
=   new  FlowStep
            {
                Action 
=   new  TryCatch
                {
                    DisplayName 
=   " Try/Catch for Divide By Zero Exception " ,
                    Try 
=   new  Assign
                    {
                        DisplayName 
=   " discount = 15 + (1 - 1/numberOfKids)*10 " ,
                        To 
=   new  OutArgument < double > (discount),
                        Value 
=   new  InArgument < double > ((ctx)  =>  ( 15   +  ( 1   -   1   /  numberOfKids.Get(ctx))  *   10 ))
                    },
                    Catches 
=  
                    {
                         
new  Catch < System.DivideByZeroException >
                         {
                             Action 
=   new  ActivityAction < System.DivideByZeroException >
                             {
                                 Argument 
=  ex,
                                 DisplayName 
=   " ActivityAction - DivideByZeroException " ,
                                 Handler 
=
                                     
new  Sequence
                                     {
                                         DisplayName 
=   " Divide by Zero Exception Workflow " ,
                                         Activities 
=
                                         {
                                            
new  WriteLine() 
                                            { 
                                                DisplayName 
=   " WriteLine: DivideByZeroException " ,
                                                Text 
=   " DivideByZeroException: Promo code is MWK - but number of kids = 0 "  
                                            },
                                            
new  Assign < double >
                                            {
                                                DisplayName 
=   " Exception - discount = 0 "
                                                To 
=  discount,
                                                Value 
=   new  InArgument < double > ( 0 )
                                            }
                                         }
                                     }
                             }
                         }
                    }
                },
                Next 
=  flowDecision
            };

            FlowStep discountDefault 
=   new  FlowStep
            {
                Action 
=   new  Assign < double >
                {
                    DisplayName 
=   " Default discount assignment: discount = 0 " ,
                    To 
=  discount,
                    Value 
=   new  InArgument < double > ( 0 )
                },
                Next 
=  flowDecision
            };

            FlowSwitch
< string >  promoCodeSwitch  =   new  FlowSwitch < string >
            {
                Expression 
=  promo,
                Cases 
=
                {
                   { 
" Single " , singleStep },
                   { 
" MNK " , mnkStep },
                   { 
" MWK " , mwkStep }
                },
                Default 
=  discountDefault
            };

            Flowchart flowChart 
=   new  Flowchart
            {
                DisplayName 
=   " Promotional Discount Calculation " ,
                Variables 
=  { discount, promo, numberOfKids },
                StartNode 
=  promoCodeSwitch,
                Nodes 
=  
                { 
                    promoCodeSwitch, 
                    singleStep, 
                    mnkStep, 
                    mwkStep, 
                    discountDefault, 
                    flowDecision, 
                    discountApplied, 
                    discountNotApplied
                }
            };
            
return  flowChart;
        }

     }

 调用:

  WorkflowInvoker.Invoke( new  FlowChartActivity( " MWK " 2 ));

    注意这个自定义活动实现与前面两个的区别,它在构造函数中指定实现活动的方法,而这个方法返回Activity类型。

4、NativeActivity

    这个活动是四种活动中最强大的一个,实现起来非常的灵活。WF4.0中内置的Sequence 、While 、If、Parallel 等活动都继承此类。如果前面三种都实现不了,这个活动可能能实现你需要的功能。例如自定一个While:

代码
public   sealed   class  MyWhile : NativeActivity
    {
        Collection
< Variable >  variables;

        
public  MyWhile()
        {
            
this .variables  =   new  Collection < Variable > ();
        }

        
public  Collection < Variable >  Variables
        {
            
get
            {
                
return   this .variables;
            }
        }

        
public  Activity < bool >  Condition  {  get set ; }
        
public  Activity Body {  get set ; }

        
protected   override   void  CacheMetadata(NativeActivityMetadata metadata)
        {
            
// call base.CacheMetadata to add the Variables, Condition, and Body to the activity's metadata
             base .CacheMetadata(metadata);

            
if  ( this .Condition  ==   null )
            {
                
// MyWhile requires a Condition expression so - add a validation error if one isn't present
                metadata.AddValidationError( string .Format( " While {0} requires a Condition " this .DisplayName));
                
return ;
            }
        }        

        
protected   override   void  Execute(NativeActivityContext context)
        {
            InternalExecute(context, 
null );
        }

        
void  InternalExecute(NativeActivityContext context, ActivityInstance instance)
        {
            
// schedule the Condition for evaluation
            context.ScheduleActivity( this .Condition,  new  CompletionCallback < bool > (OnEvaluateConditionCompleted));
        }

        
void  OnEvaluateConditionCompleted(NativeActivityContext context, ActivityInstance instance,  bool  result)
        {            
            
if  (result)
            {
                
if  ( this .Body  !=   null )
                {
                    
// if the Condition evaluates to true and the Body is not null
                    
// schedule the Body with the InternalExecute as the CompletionCallback
                    context.ScheduleActivity( this .Body, InternalExecute);
                }
            }

        }
    }

     简单的看下这个MyWhile,很简单分两个部分看:属性和方法。属性有variables、Condition、和Body。方法有构造函数、CacheMetadata、Execute、OnEvaluateConditionCompleted。CacheMetadata、Execute覆盖父类的方法。ScheduleActivity完成之后执行OnEvaluateConditionCompleted。

总结:WF4.0的资料不多,但是相对WF3.0和3.5简单很多,自定义活动是非常重要学习内容。



(全文完)


以下为广告部分

您部署的HTTPS网站安全吗?

如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

SSL检测评估

快速了解HTTPS网站安全情况。

安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

SSL证书工具

安装部署SSL证书变得更方便。

SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

SSL漏洞检测

让服务器远离SSL证书漏洞侵扰

TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

转载于:https://www.cnblogs.com/zhuqil/archive/2010/02/26/WF-Activity.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值