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);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM