zoukankan      html  css  js  c++  java
  • WorkFlow工作流

    一、WorkFlow介绍

    1. WorkFlow是OA系统中必不可少的模块,并且在以后的大多数的工作中,都会用到工作流模式的开发。关于这方面的开发,我第一次接触到的是关于钉钉里的氚云功能,感觉还是做的相当不错,用户只需要拖动控件,然后配置数据库,就会形成对应的工作流,并不需要大量的代码编写。

    二、创建一个demo案例:

    1. 这儿创建的是一个控制台程序demo。

     主程序代码如下:

    using System;
    using System.Linq;
    using System.Activities;     //主要的
    using System.Activities.Statements;
    
    namespace WorkflowConsoleApplication1
    {
    
        class Program
        {
            static void Main(string[] args)
            {
                //new了一个工作流类
                Activity workflow1 = new Workflow1();
                //启动工作流
                WorkflowInvoker.Invoke(workflow1);
                Console.ReadLine();
            }
        }
    }

    其中需要注意的是inputCodeActivity1,该控件是一个代码活动,就是指此处需要一些别的操作,具体创建如下:

    并且编辑如下代码,提供一个返回参数:

        public sealed class inputCodeActivity1 : CodeActivity
        {
            // 定义一个字符串类型的活动输入参数
            //public InArgument<string> Text { get; set; }
            //输出参数
            public OutArgument<int> returnMoney { get; set; }
    
            // 如果活动返回值,则从 CodeActivity<TResult>
            // 派生并从 Execute 方法返回该值。
            protected override void Execute(CodeActivityContext context)
            {
                // 获取 Text 输入参数的运行时值
                //string text = context.GetValue(this.Text);
                int m;
                string money = Console.ReadLine();
                int.TryParse(money, out m);
                //为输出参数设置参数
                context.SetValue(returnMoney,m);
            }
        }

    最终全部创建好,之后,如下:

     最终的运行结果如下:

     备注:4.0版本的没有状态机工作流,需要切换到别的版本才有

    三、 WorkflowApplication启用工作流以及传参,与常用触发事件。

    1. WorkflowApplication提供了很多的触发事件,每当工作流执行到某一状态的时候,就会触发该工作流里的方法,并且进行实时监控,所以目前工作流的启动,都是使用该类来完成。

    2. case:

     定义一个winform窗体应用界面

    button对应代码如下:

     private void btnStartWorkFlow_Click(object sender, EventArgs e)
            {
                //定义一个字典
                var dict = new Dictionary<string, object>() { { "tempDateTime", DateTime.Now } };
                //工作流的类,
                //WorkflowApplication wfApp = new WorkflowApplication(new Activity1());
                //重载的第二种,传递一个参数过去,但是必须是键值对的形式。
                WorkflowApplication wfApp = new WorkflowApplication(new Activity1(),dict);
                //信号量机制类
                AutoResetEvent syncEvent = new AutoResetEvent(false);
                wfApp.Run();
            }

    工作流中如下:此处的参数必须和传递的参数值一致。

    3. 常用触发事件。

     private void btnStartWorkFlow_Click(object sender, EventArgs ex)
            {
                Console.WriteLine("主线程:"+Thread.CurrentThread.ManagedThreadId);
                var dict = new Dictionary<string, object>() { { "TempDateTime", DateTime.Now }, { "TempBookMarkName",this.txtBookMarkName.Text} };
                AutoResetEvent syncEvent = new AutoResetEvent(false);  //主线程信号量
                 wfApp = new WorkflowApplication(new Activity1(), dict);//第二个参数是给工作流传参,这里的参数名TempDateTime,必须和工作流中定义的参数名称一致.
                //-----------------------常用触发事件---------------------
                //工作流执行完成之后触发里面代码,
                wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
                {
                    Console.WriteLine("工作流执行完成");
                    syncEvent.Set();  //唤起主线程
                };
                //强制终止触发
                wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
                {
                    Console.WriteLine("工作流终止");
                    syncEvent.Set();
                };
                //处于空闲状态触发
                wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e)
                    {
                        Console.WriteLine("工作流空闲");
                        syncEvent.Set();
                    };
                //工作流持久化,就是指例如把当前的数据录入到数据库中
                wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                    Console.WriteLine("工作流持久化");
                    syncEvent.Set();
                    return PersistableIdleAction.Unload;  //工作流卸载
                };
                //卸载之后触发
                wfApp.Unloaded = delegate(WorkflowApplicationEventArgs e)
                {
                    Console.WriteLine("工作流卸载");
                    syncEvent.Set();
                };
                //发生异常触发的时间
                wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
                {
                    Console.WriteLine("工作流异常了");
                    syncEvent.Set();
                    return UnhandledExceptionAction.Abort;
                };
                // Start the workflow.
                wfApp.Run();//开始执行设计好的工作流,这里会会开启一个新的线程。
                syncEvent.WaitOne();  //阻止主线程,直到当前收到信号。
    
                Console.WriteLine("继续执行后面的代码");
            }

    四、线程信号量类介绍:

    1. new一个线程信号量 

     AutoResetEvent syncEvent = new AutoResetEvent(false);  //主线程信号量

    上方代码中主要使用到了如下两个方法;

    syncEvent.Set();  //唤起主线程
    syncEvent.WaitOne();  //阻止主线程,直到当前收到信号。

     五、 BookMark(书签)

    1. 就是指执行到该结点处暂停,等待开启的命令,然后继续执行。

    2. 就是指修改创建的代码活动类。本来是继承CodeActivity类,现在改为继承NativeActivity,并且重新其中提供的抽象方法,注释掉原本的方法,创建Bookmark书签,需要提供两个参数,一个是书签名,一个是需要执行的方法,相关代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Activities;
    namespace WindowsFormsApplication1
    {
        //修改使其继承 NativeActivity
        public sealed class Wait4BookMarkCodeActivity :NativeActivity
        {
            // 定义一个字符串类型的活动输入参数
            public InArgument<string> BookMarkName { get; set; }
            public OutArgument<int> ReturnResult { get; set; }
    
            // 如果活动返回值,则从 CodeActivity<TResult>
            // 派生并从 Execute 方法返回该值。
            //protected override void Execute(CodeActivityContext context)
            //{
            //    // 获取 Text 输入参数的运行时值
            //    string text = context.GetValue(this.Text);
            //}
    
            /// <summary>
            /// 自动调用该方法,在该方法中完成BookMark的创建
            /// </summary>
            /// <param name="context"></param>
            protected override void Execute(NativeActivityContext context)
            {
                //拿到输入参数的值
                string bookMarkName = context.GetValue(BookMarkName);
                //创建bookMark,第一个是他的名字,第二个是传递一个委托事件         ,并且唤醒bookMark。
                //以下等同于,第一个参数是名字,第二个参数是一个方法。
                context.CreateBookmark(bookMarkName, ExecuteContinue);
            }
            protected override bool CanInduceIdle
            {
                get
                {
                    return true;
                }
            }
            /// <summary>
            /// 当下次唤起BookMark,那么该方法被执行.
            /// </summary>
            /// <param name="context"></param>
            /// <param name="bookmark"></param>
            /// <param name="value"></param>
            public void ExecuteContinue(NativeActivityContext context, Bookmark bookmark, object value)
            {
                int i = Convert.ToInt32(value);
                context.SetValue(ReturnResult,i);
            }
        }
    }
  • 相关阅读:
    计算机执行程序代码的过程分析
    iOS 操作系统架构
    ios 概况了解
    android ApplicationContext Context Activity 内存的一些学习
    android 内存优化一
    android 学习
    ios 基础学习二
    ios 集合总结
    线程之间的通讯---SynchronizationContext
    ASP.NET Core 身份验证及鉴权
  • 原文地址:https://www.cnblogs.com/wangjinya/p/10924581.html
Copyright © 2011-2022 走看看