实现WF状态机动态跳转功能

Posted on 2008-08-30 17:27  icewater  阅读(1770)  评论(1)    收藏  举报

前段时间应客户要求,需要把工作流设计成每个节点(stateActivity)都需要自由跳转.

 

比如有一个工作流画好的模板,按工作顺序运行下来就是:输入->提交服务->输出.

 

当开发业务的时候,写业务的程序员必须要加载这工作流模板,按设计好的顺序运行,写的逻辑只写输入时要怎么处理,输出时要怎么处理而已.

不过,要允许在这个工作流的这几个节点间暴露可以重写的方法,以便可以在每个节点运行前后作一些自己要处理的逻辑.

 

现在他们要在这些重写的代码中加入GOTO语句,可以自由写GOTO把工作流的状态改变,比如,当运行到结束点前时,发现最后得到的数据中有不满意的地方要重新运行,就必须可以写一个GOTO(stepname);直接跳到开始节点.

 

一开始以为很容易实现.没做太大的考虑就答应了.

 

后台真正做到时,才发现是有问题的,在当前工作流实例线程正在运行时,是不能随意的用SETSTATE()方法改变状态,要改的话WF只支持,预先设计好到达这个节点会有什么情况,然后用IFELSEActivity再改变流转.但这样的确太死,就是说你要做到所有情况都必须考虑好,然后在画工作流时设计好.这样就满足不了以后情况有变化的问题,多一个条件就得改一次工作流图加多一个判断,如果条件非常多,比如有几十个以上,那这个图我想必定混乱了.

 

后来终于想了一个技巧去解决这个问题,就是按照状态机的事件驱动方式去处理,但发送事件的是要新开一个线程去处理,这样第一个线程在处理到这个外部节点时如果需要GOTO就起另一个线程去SETSTATE,当然,在GOTO前,调用业务处理的代码比较完成并且返回到,状态机便处于等待状态,这样用第二个线程去SETSTATE就不会有问题了.

 

说得有点乱,以后再整理一下,如果那位朋友也遇到此类问题可以一起探讨解决.目前我的这个问题已经可以解决,当然还必须要做一下优化.

最后,简单的贴一下相关的代码:

 

        #region 异步线程GOTO到目标步骤
        public static void GoTo(WFSubmitContext context)
        {
            Thread td = new Thread(new ParameterizedThreadStart(GotoNextSetp));
            td.IsBackground = true;
            td.Start(context);
        }
        static void GotoNextSetp(object data)
        {
            WFSubmitContext context = data as WFSubmitContext;

            string nextStep = context.Parameters["GotoStep"] as string;

            if (string.IsNullOrEmpty(nextStep)) throw new Exception("要跳转的目标步骤名不能为空!");

            StateMachineWorkflowInstance stateInstance = new StateMachineWorkflowInstance(Runtime, context.InstanceID);
            stateInstance.SetState(nextStep);
        }
        #endregion

 

            

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3