2008年8月30日

前段时间应客户要求,需要把工作流设计成每个节点(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

 

            

posted @ 2008-08-30 17:27 icewater 阅读(1228) 评论(1) 编辑


2008年8月18日

当开始工作流时,发现某一工作流实例没能按照画定的流程图正常运行,而是运行到一半时自动关闭.

 

由于初学WF,没太多经验,看了好几篇高手介绍WF异常处理的文章,

照葫芦画葫芦得加上了FaultHandlerActivity,ThrowActivity 等,但就是怎么弄也找不到出错的这个Exception,超级郁闷,还是第一次找个Exception找了那么久都找不到的.

 

后来看到一文介绍:

 

如果异常没有被处理并且传播到工作流之外,那么WF Runtime将捕获它,接着终止工作流并抛出WorkflowTerminated事件.Runtime会在WorkflowTerminated事件的参数中包含异常的信息.

 

终于帮到了大忙,这样应该可以找到了吧,在定义RUNTIME那里加上:

 

workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(workflowRuntime_WorkflowTerminated);

static void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
{
      Console.WriteLine("workflow实例已终止,原因:'{0}'。",e.Exception.Message);
}

 

马上运行,终于找到这个Exception了,而出错的原因是因为我用了实现[DataContract]的类型,但赋给它的变量没加序列化的标签而引起的,超级郁闷,马上加上,运行工作流,整个流程顺利跑完!!!!

 

哎,如果早点发现就好了,搞了2天去查这个错误到底是什么错,真是超级郁闷.

或许是学习WF还不够深入的原因吧.

 

把这次的教训经验写一下,希望能给别人也有所帮助.不用像我那样花2天去找这个BUG.

 

posted @ 2008-08-18 16:40 icewater 阅读(1352) 评论(2) 编辑


  

posts - 2, comments - 3, trackbacks - 1, articles - 0

Copyright © icewater