簡介
WF兼有很多角色,如編程模型、運行時引擎以及工具集等,它使我們很容易建立基於工作流程的應用。這裡主要分析一下VS2008下順序工作流程控制台應用程式的模板,並瞭解幾個常見的活動。
順序工作流程控制台應用程式模板
WF提供兩種類型的工作流程:順序工作流程、狀態機器工作流程。這兩個工作流程分別從SequentialWorkflowActivity, StateMachineWorkflowActivity派生而來。VS2008提供了順序工作流程控制台應用程式和類庫兩種模板,本文主要介紹順序工作流程控制台應用程式模板。
建立工作流程項目
具體步驟省略,詳細請參見參考文獻所示。查看產生的工作流程代碼如下:
Code
public sealed partial class Workflow1: SequentialWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
}
}
很容易看出,建立的工作流程Workflow1是從SequentialWorkflowActivity派生。
建立的工作流程只有起始點,沒有任何活動。這裡我們添加一個Code activity。添加了這個活動後,我們發現,這個活動出現了錯誤,是因為ExecuteCode沒有設定,這裡只需雙擊Code activity即可,並在代碼檔案中添加Console.WriteLine("Hello, World!");。一個Hello, World!工作流程就這樣完成了。解析工作流程調用代碼(宿主程式碼)
Code
static void Main(string[] args)
{
// 建立工作流程運行時引擎,為工作流程初始化提供可配置的運行環境
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
// 防止工作流程線程沒有執行完成,主線程就退出。
// 工作流程線程完成後,通過Set方法通知主線程,工作流程線程已經完成。
AutoResetEvent waitHandle = new AutoResetEvent(false); // 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(WorkflowDemo1.Workflow1));
instance.Start();
// 主線程在此阻塞,直到工作流程線程發出通知(waitHandle.Set())
waitHandle.WaitOne();
}
}
注意:
1. 通過WorkflowRuntime類為工作流程初始化提供可配置的運行環境
2. 通過AutoResetEvent類,協調主線程和工作流程線程。
3. 通過WorkflowInstance類建立工作流程執行個體。
建立一個比Hello, World更進階的工作流程
作業:建立一個工作流程,使之支援一個檔案加中的所有檔案拷貝到另外一個檔案夾。
思路:
1.建立一個代碼活動,解析從宿主程式傳來的源檔案夾和目的檔案夾;
2.建立一個迴圈活動(一個個拷貝,直到所有檔案拷貝完畢)
在迴圈活動中內嵌程式碼活動,完成單個檔案的拷貝
這裡需要解釋幾個問題:
迴圈活動條件設定
在while activity活動中,規則採用聲明性規則條件,當前是第幾個檔案 < 總共幾個檔案。在後台產生如下檔案workflow.rules:
Code
<RuleDefinitions xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<RuleDefinitions.Conditions>
<RuleExpressionCondition Name="條件1">
<RuleExpressionCondition.Expression>
<!--操作符定義為小於符號-->
<ns0:CodeBinaryOperatorExpression Operator="LessThan" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<!--左邊的值-->
<ns0:CodeBinaryOperatorExpression.Left>
<ns0:CodeFieldReferenceExpression FieldName="currentFile">
<ns0:CodeFieldReferenceExpression.TargetObject>
<ns0:CodeThisReferenceExpression />
</ns0:CodeFieldReferenceExpression.TargetObject>
</ns0:CodeFieldReferenceExpression>
</ns0:CodeBinaryOperatorExpression.Left>
<!--右邊的值-->
<ns0:CodeBinaryOperatorExpression.Right>
<ns0:CodePropertyReferenceExpression PropertyName="totalFiles">
<ns0:CodePropertyReferenceExpression.TargetObject>
<ns0:CodeThisReferenceExpression />
</ns0:CodePropertyReferenceExpression.TargetObject>
</ns0:CodePropertyReferenceExpression>
</ns0:CodeBinaryOperatorExpression.Right>
</ns0:CodeBinaryOperatorExpression>
</RuleExpressionCondition.Expression>
</RuleExpressionCondition>
</RuleDefinitions.Conditions>
</RuleDefinitions>
在後台,通過
System.Workflow.Activities.Rules.RuleConditionReference ruleconditionreference1 = new System.Workflow.Activities.Rules.RuleConditionReference();
ruleconditionreference1.ConditionName = "條件1";
this.whileActivity1.Condition = ruleconditionreference1;
進行載入到迴圈活動中。
宿主程式和工作流程的通訊
如何向工作流程中傳遞參數:
在工作流程中定義成員變數:
public string toFolder { get; set; }
public string fromFolder { get; set; }
public int totalFiles { get; set; }
在宿主程式初始化工作流程執行個體的時候,將參數傳入
var parameters = new Dictionary<string, object>();
parameters.Add("fromFolder", @"K:"test");
parameters.Add("toFolder", @"K:"backup");
WorkflowInstance instance =
workflowRuntime.CreateWorkflow(
typeof(WorkflowDemo1.Workflow1), parameters);
如何從工作流程中擷取參數:
從WorkflowCompletedEventArgs e 中,即可擷取工作流程中的相關資訊,如:e.OutputParameters["totalFiles"]。
參考文獻
本翻譯沒有按照原文,詳細請查閱
http://social.msdn.microsoft.com/content/en-us/msft/netframework/wf/learn/Intro-SequentialWorkflows