当前位置: 代码迷 >> 综合 >> 中断工作流并持久化到数据库中
  详细解决方案

中断工作流并持久化到数据库中

热度:21   发布时间:2024-01-21 23:58:52.0

中断工作流并持久化到数据库中

工作流图如下:


说明:工作流中的行为为自定义行为。该工作流的执行流程如下:张三,李四与王五三个审核稿件,三个人必须通过才通过,如果不通过则继续审核,直到通过为止。

如果不通过,则将数据持久化到数据库中,并中断工作流的执行。可以通过加载工作流再次执行工作流。

自定义的审核行为代码如下:

[PersistOnClose()] //  必须有该属性,该属性是表示在执行该行为结束后持久化工作流

public  partial  class  AuditingActivity: Activity

{

    
public  AuditingActivity()

    {

        InitializeComponent();

    }

    
///   <summary>

    
///  自定义UserName(用户名)属性

    
///   </summary>

    
public   static  DependencyProperty UserNameProperty  =  DependencyProperty.Register( " UserName " ,  typeof ( string ),  typeof (AuditingActivity));

    
public   string  UserName

    {

        
get

        {

            
return  ( string ) base .GetValue(AuditingActivity.UserNameProperty);

        }

        
set

        {

            
base .SetValue(AuditingActivity.UserNameProperty, value);

        }

    }

    
///   <summary>

    
///  重写行为的执行方法

    
///   </summary>

    
///   <param name="executionContext"></param>

    
///   <returns></returns>

    
protected   override  ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

    {

        Console.Write(
" {0}用户审核结果:  " , UserName);

        
if  (Console.ReadLine().ToLower()  ==   " true " )

        {

            Console.WriteLine(
" {0}用户审核通过 " , UserName);

        }

        
else

        {

            Console.WriteLine(
" {0}用户审核不通过 " , UserName);

            
//  进入空闲状态。在空闲状态中中断工作流。

            
//  不能在行为内部调用WorkflowInstance.Abort()等方法。

            
return  ActivityExecutionStatus.Executing;

        }

        
return  ActivityExecutionStatus.Closed;

    }

}

工作流运行时引擎代码如下:

///   <summary>

///  工作流运行时引擎类

///   </summary>

public   class  Runtime:IDisposable

{

    WorkflowRuntime workflowRuntime 
=   null ;

    ManualWorkflowSchedulerService manualWorkflowSchedulerService 
=   null ;

    
///   <summary>

    
///  初始化工作流引擎的服务与事件,并运行工作流引擎

    
///   </summary>

    
public  Runtime()

    {

        workflowRuntime 
=   new  WorkflowRuntime();

        
//  需要将SqlWorkflowPersistenceService服务的unloadOnIdle参数设置为false表示不让工作流在空闲或卸载时自动持久化。

        
//  如果设置为true,将会在unload()执行后自动持久化工作流,这将导致无法正常加载工作流。

        workflowRuntime.AddService(
new  SqlWorkflowPersistenceService( " server=(local);database=AuditingWorkflow;integrated security=sspi " ,  false ,  new  TimeSpan( 0 ,  0 ,  5 ),  new  TimeSpan( 0 ,  0 ,  10 )));

        
//  添加手动调度服务

        manualWorkflowSchedulerService 
=   new  ManualWorkflowSchedulerService();

        workflowRuntime.AddService(manualWorkflowSchedulerService);

        workflowRuntime.WorkflowCompleted 
+=   delegate ( object  sender, WorkflowCompletedEventArgs e)

        {

            Console.WriteLine(
" {0}工作流结束 " , e.WorkflowInstance.InstanceId);

        };

        workflowRuntime.WorkflowTerminated 
+=   delegate ( object  sender, WorkflowTerminatedEventArgs e)

        {

            Console.WriteLine(
" {0}工作流终止 " , e.WorkflowInstance.InstanceId);

        };

        workflowRuntime.WorkflowIdled 
+=   delegate ( object  sender, WorkflowEventArgs e)

        {

            e.WorkflowInstance.Abort();

            Console.WriteLine(
" 中断了{0}工作流 " , e.WorkflowInstance.InstanceId);

        };

        workflowRuntime.WorkflowPersisted 
+=   new  EventHandler < WorkflowEventArgs > (workflowRuntime_WorkflowPersisted);

        workflowRuntime.StartRuntime();

    }

 

    
void  workflowRuntime_WorkflowPersisted( object  sender, WorkflowEventArgs e)

    {

        Console.WriteLine(
" {0}工作流持久化 " ,e.WorkflowInstance.InstanceId);

    }

    
///   <summary>

    
///  获取工作流调度

    
///   </summary>

    
public  ManualWorkflowSchedulerService WorkflowScheduler

    {

        
get

        {

            
return  manualWorkflowSchedulerService;

        }

    }

    
///   <summary>

    
///  通过工作流类型创建工作流的实例

    
///   </summary>

    
///   <param name="workflowType"></param>

    
///   <returns></returns>

    
public  Guid CreateWorkflow(Type workflowType)

    {

        WorkflowInstance instance 
=  workflowRuntime.CreateWorkflow(workflowType);

        Console.WriteLine(
" 创建了{0}工作流 " , instance.InstanceId);

        
//  先将工作流开始,再将工作流卸载,这个顺序不能变动。否则将在创建的时候就运行了工作流并且如果第一个审核行为不通过,就不能正常加载了

        instance.Start();

        instance.Unload();

 

        
//  必须执行该语句,否则无法正常加载工作流,具体原因还不太清楚,跟踪工作流的时候,有没有执行该语句的工作流执行状态是一样的

        
//  初步分析是因为执行Start()方法并没有真正的执行工作流(因为该引擎用了ManualWorkflowSchedulerService服务),直到调用RunWorkflow()方法时才执行工作流

        manualWorkflowSchedulerService.RunWorkflow(instance.InstanceId);

        
return  instance.InstanceId;

    }

    
///   <summary>

    
///  通过工作流ID加载工作流

    
///   </summary>

    
///   <param name="workflowGuid"></param>

    
public   void  LoadWorkflow(Guid workflowGuid)

    {

        
//  通过工作流ID获取工作流实例

        WorkflowInstance instance 
=  workflowRuntime.GetWorkflow(workflowGuid);

        
if  (instance  ==   null )

            
return ;

        
//  加载工作流

        instance.Load();

        
//  通过调度服务运行工作流

        manualWorkflowSchedulerService.RunWorkflow(instance.InstanceId);

    }

    
///   <summary>

    
///  资源清理

    
///   </summary>

    
public   void  Dispose()

    {

        
if  (workflowRuntime  !=   null )

            workflowRuntime.Dispose();

    }

}

客户端代码如下:

class  Program

{

    
static   void  Main( string [] args)

    {

        
//  实例化工作流运行时引擎,该类的实例最好在系统初始化时实例化,在系统结束后执行Dispose()方法

        Runtime runtime 
=   new  Runtime();

        
string  input  =   null ;

        Console.Write(
" 请输入命令:  " );

        
while  ((input  =  Console.ReadLine().ToLower())  !=   " end " )

        {

            
switch  (input)

            {

                
case   " create " :  //  创建工作流

                    runtime.CreateWorkflow(
typeof (BreakWorkflowAndPersistenceToDatabase.AuditingWorkflow));

                    
break ;

                
case   " load " :  //  通过工作流ID加载工作流

                    Console.Write(
" 请输入工作流ID:  " );

                    
try

                    {

                        Guid guid 
=   new  Guid(Console.ReadLine());

                        runtime.LoadWorkflow(guid);

                    }

                    
catch  (Exception ex)

                    {

                        Console.WriteLine(
" 加载工作流出错!原因:{0} " , ex.Message);

                    }

 

                    
break ;

            }

            Console.Write(
" 请输入命令:  " );

        }

    }

}

执行结果如下:

注意:在输入命令的时候要快,不然会失效,可能原因是因为工作流的行为在运行过程中有运行时间控制,如果在某个时间内工作流行为(activity)处于不执行状态则中止工作流执行。也可能因为线程的切换导致的。目前我还没有分析出具体原因。望高手们能够帮忙找出原因。

 
  相关解决方案