|
1. 什么是工作流
我給工作流下了這樣的定義,工作流就是一個過程,這個過程會產(chǎn)生一定的結(jié)果。
其實,在OA系統(tǒng)中,審批流就是我們最常見的工作流之一。
另外,簡單了說,其實我們所畫的流程圖就是一種最簡單的工作流,工作流最大的特點就是圖形化。工作流是按照順序驅(qū)動或者事件驅(qū)動去觸發(fā)下一步操作,從而最終得到一個結(jié)果。
其實,我們也可以把他理解為一個過程化的職責(zé)鏈。
2. 工作流的類型
工作流大致分為兩類,順序工作流和事件驅(qū)動工作流。
順序工作流是我們很常見的工作流,這個工作流是由我們事先規(guī)定好的順序一步步地走下去,他們執(zhí)行的步驟是不可以改變的。
事件驅(qū)動工作流,我們也稱之為有限狀態(tài)機(jī),他狀態(tài)的變更是猶由于特定的事件而觸發(fā)的。
舉例如下:
順序工作流:審批流其實就是典型的順序工作流,一個審批對象一步步地層層審批,拿一次面試過程來說,首先人事部簡歷篩選,然后是技術(shù)經(jīng)理面試,然后是總經(jīng)理面試,這都是按照流程來的。
事件驅(qū)動工作流:想想我們的軟件工程流程,是不是這樣的:
3. 第一個實例:Hello world
學(xué)任何程序,第一個例子往往都是Hello world,這次也不例外。
讓我們先來構(gòu)建一個簡單的WF小程序。
我所使用的環(huán)境是Visual Studio 2008 + .NET Framework 3.5 sp1來搭建項目:
首先讓我們來熟悉環(huán)境:
打開VS2008,選擇新建——> 項目:
然后選擇Workflow——>順序工作流控制臺應(yīng)用程序。然后點擊確定就進(jìn)入了我們的WF項目中。
在項目中,我們可以看到Program.cs和Workflow1.cs。Workflow1我不多說,這個當(dāng)然是我們的工作流程序。
那來看一下Program.cs:
4. 宿主
Windows workflow foundation不是一個獨立的產(chǎn)品,他需要在一個宿主的環(huán)境下才能運行。
這個宿主可以是控制臺應(yīng)用程序,Winform程序,也可以是ASP.NET程序。
WF的運行是通過工作流的運行時引擎來實現(xiàn)的。實際上,工作流運行時引擎和宿主的應(yīng)用程序在同一進(jìn)程中。
5. 繼續(xù)Hello world
在工具箱中,拖出一個Code控件。
然后為codeActivity1起一個有意義的Name為codeActivityHello。
然后去實現(xiàn)ExcuteCode事件,實現(xiàn)這個事件,運行庫將自動調(diào)用這個方法。
實現(xiàn)如下:
private void codeActivityHello_ExecuteCode(object sender, EventArgs e){ Console.WriteLine("Hello world");}
好了,讓我們運行這段程序:
6. 深入解析宿主文件
讓我們進(jìn)一步地去解析宿主文件Program.cs:
static void Main(string[] args){ using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) { AutoResetEvent waitHandle = new AutoResetEvent(false); workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();}; workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) { Console.WriteLine(e.Exception.Message); waitHandle.Set(); }; WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication3.Workflow1)); instance.Start(); waitHandle.WaitOne(); }}
WorkflowRuntime:為工作流執(zhí)行引擎提供了可執(zhí)行環(huán)境。
接下來,workflowRuntime.WorkflowCompleted事件和workflowRuntimeTerminated分別指定了工作流執(zhí)行結(jié)束和執(zhí)行終止時所調(diào)用的匿名方法。
接下來創(chuàng)造一個相應(yīng)的工作流的實例,然后讓這個實例開始執(zhí)行。
而后去調(diào)用AutoResetEvent的實例waitHandle.WaitOne()作用在于阻止當(dāng)前線程的執(zhí)行,從而讓該工作流進(jìn)行結(jié)束后,即WorkflowRuntime.WorkflowComplete事件技術(shù)后,我們再可以在這條語句后來調(diào)用執(zhí)行其他的語句。
沒什么好說的了,接下來去創(chuàng)建一個工作流的實例,然后開始執(zhí)行。
7. 讓程序更有趣一些
分析過宿主文件之后,那我們開始讓程序更有趣一些。
而手腳就讓我們從那兩個匿名方法開始。
首先修改workflow1.cs 的 后臺代碼:
public sealed partial class Workflow1 : SequentialWorkflowActivity{ public Workflow1() { InitializeComponent(); } private string message; public string Message { get { return message; } } private void codeActivityHello_ExecuteCode(object sender, EventArgs e) { this.message = "Hello world"; }}
當(dāng)工作流執(zhí)行的時候,他就給Workflow1類所實例化的對象中的Message屬性賦值為Hello world。我們需要做的是將這個Message獲取出來。
先讓我們來看看本質(zhì),其實,在工作流的對象中,所有的屬性都是以鍵值對的形式存儲在哈希表中,因此,我們可以通過WorkflowCompleteEventArgs參數(shù)將對應(yīng)的屬性得到,代碼如下:
string message = String.Empty;workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { message = e.OutputParameters["Message"].ToString(); waitHandle.Set();};
接下來,我們就可以打印出message了。
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication3.Workflow1));instance.Start();waitHandle.WaitOne();Console.WriteLine(message);
8. 進(jìn)一步改造程序
既然我們可以獲得參數(shù),當(dāng)然也可以向工作流中傳入?yún)?shù)。
讓我們先來改造一下workflow1.cs的后臺代碼文件:
public sealed partial class Workflow1 : SequentialWorkflowActivity{ public Workflow1() { InitializeComponent(); } private string message; public string Message { get { return message; } } private string input; public string Input { set { input = value; } } private void codeActivityHello_ExecuteCode(object sender, EventArgs e) { this.message = "Hello " + input; }}
向工作流中傳入?yún)?shù)其實很簡單,讓我們來注意一下這個方法:
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication3.Workflow1));
這個方法通過傳入一個類型來實例化一個對應(yīng)的工作流實例,當(dāng)然,我們就是運用這個方法的重載方法去傳入對應(yīng)的實例:
Console.WriteLine("Please input your name:");string input = Console.ReadLine();Dictionary<string, object> dic = new Dictionary<string, object>();dic.Add("Input", input);WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication3.Workflow1),dic);instance.Start();waitHandle.WaitOne();Console.WriteLine(message);
看看效果:
9. 總結(jié)
以上是工作流的最簡單的一個例子,敬請關(guān)注下文。
NET技術(shù):一步一步學(xué)WF系列(一)Hello world開始,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。