WF-全扫描(3)-补偿(B):

下面这篇博文转载自http://cnblogs.com/ 生鱼片的文章,这篇文章是基于WF3.5阐述的补偿的具体概念。在WF4.0中补偿又有了新的变化。从理解概念的角度,下面这篇文章很有启发意义:

以一个具体的例子来说明补偿是如果使用的,假如你计划要去旅游,那么你在出发前会先定火车票,然后在定酒店。那么如果你定到火车票了,可是当你去定酒店的时候你发现所有的酒店都已经被别人预定了,这个时候你定的火车票也没有用了,只好退订了。在我们的程序中我们用补偿来完成这个功能。下图是我们设计的工作流:

坚持学习WF(17):WF中的补偿 

假设我们有这样一个设计流程,首先预定火车票,然后在预定酒店,在预定酒店的时候我们会判断是否成功。如果不成功我们会抛出一个异常。在预定火车票活动(BookTicket)放到了CompensatableTransactionScopeActivity活动中,其中的补偿处理我们执行退订火车票的程序,如下图:

坚持学习WF(17):WF中的补偿

  在预定酒店的时候,如果预定不成功我们会使用上图中的BookFail(ThrowActivity)活动来抛出一个异常,下面是我们自定义的一个异常类,代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.Serialization;namespace CaryCompensationDemo{  [SerializableAttribute()]  public class BookHotelException : Exception  {    public BookHotelException() : base()    { }    public BookHotelException(string message) : base(message)    { }    public BookHotelException(string message, Exception innerException)       : base(message, innerException)    { }    protected BookHotelException(SerializationInfo info, StreamingContext context)       : base(info, context)    { }  }}

  在整个工作的错误处理程序中来捕获异常,并执行补偿处理,如下图:

坚持学习WF(17):WF中的补偿

我们使用CompensateActivity活动的TargetActivityName属性来指定对某个活动使用补偿。整个工作流的代码如下:

using System;using System.ComponentModel;using System.ComponentModel.Design;using System.Collections;using System.Drawing;using System.Linq;using System.Workflow.ComponentModel.Compiler;using System.Workflow.ComponentModel.Serialization;using System.Workflow.ComponentModel;using System.Workflow.ComponentModel.Design;using System.Workflow.Runtime;using System.Workflow.Activities;using System.Workflow.Activities.Rules;namespace CaryCompensationDemo{  public sealed partial class CaryTourWorkflow: SequentialWorkflowActivity  {    public BookHotelException discontinuedProductException1 = new BookHotelException();    public CaryTourWorkflow()    {      InitializeComponent();    }    private void TourStart_ExecuteCode(object sender, EventArgs e)    {      Console.WriteLine("准备去旅游咯");    }    private void BookTicket_ExecuteCode(object sender, EventArgs e)    {      Console.WriteLine("预定火车票");    }    private void CancelTicket_ExecuteCode(object sender, EventArgs e)    {      Console.WriteLine("退火车票");    }    private void BookHotelOK_ExecuteCode(object sender, EventArgs e)    {      Console.WriteLine("酒店预定成功");    }    private void BookOk_Condition(object sender, ConditionalEventArgs e)    {      e.Result = false;    }    private void BookHotelException_ExecuteCode(object sender, EventArgs e)    {      Console.WriteLine("没定到酒店");    }  }}

 

三:使用补偿我们需要在宿主程序中加载持久化服务,下面是宿主程序的代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Workflow.Runtime;using System.Workflow.Runtime.Hosting;namespace CaryCompensationDemo{  class Program  {    static AutoResetEvent waitHandle = new AutoResetEvent(false);    static void Main()    {      using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())      {        try        {          const string connectString = "Initial Catalog=workflowpersistence;                       Data Source=localhost;Integrated Security=SSPI;";        workflowRuntime.AddService(new SqlWorkflowPersistenceService(connectString));          workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;          workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;          workflowRuntime.WorkflowAborted += OnWorkflowAborted;          workflowRuntime.StartRuntime();          Type type = typeof(CaryCompensationDemo.CaryTourWorkflow);          workflowRuntime.CreateWorkflow(type).Start();          waitHandle.WaitOne();        }        catch (Exception ex)        {          if (ex.InnerException != null)            Console.WriteLine(ex.InnerException.Message);          else            Console.WriteLine(ex.Message);        }        finally        {          workflowRuntime.StopRuntime();        }      }    }    static void OnWorkflowAborted(object sender, WorkflowEventArgs e)    {      Console.WriteLine("请检查数据库连接是否异常");      waitHandle.Set();    }    static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e)    {      Console.WriteLine("完成工作流");      waitHandle.Set();    }    static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)    {      Console.WriteLine(e.Exception.Message);      waitHandle.Set();    }  }}

 

下面就可以运行得到执行程序: