中斷工作流并持久化到資料庫中工作流圖如下:
說明:工作流中的行為為自定義行為。該工作流的執行流程如下:張三,李四與王五三個稽核稿件,三個人必須通過才通過,如果不通過則繼續稽核,直到通過為止。
如果不通過,則将資料持久化到資料庫中,并中斷工作流的執行。可以通過加載工作流再次執行工作流。
自定義的稽核行為代碼如下:
[PersistOnClose()]// 必須有該屬性,該屬性是表示在執行該行為結束後持久化工作流
public partial class AuditingActivity: Activity
{
public AuditingActivity()
{
InitializeComponent();
}
///
<summary>
/// 自定義UserName(使用者名)屬性
///
</summary>
public
static DependencyProperty UserNameProperty = DependencyProperty.Register("UserName", typeof(string), typeof(AuditingActivity));
public
string UserName
{
get
{
return (string)base.GetValue(AuditingActivity.UserNameProperty);
}
set
{
base.SetValue(AuditingActivity.UserNameProperty, value);
}
}
///
<summary>
/// 重寫行為的執行方法
///
</summary>
///
<param name="executionContext"></param>
///
<returns></returns>
protected
override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Console.Write("{0}使用者稽核結果: ", UserName);
if (Console.ReadLine().ToLower() ==
"true")
{
Console.WriteLine("{0}使用者稽核通過", UserName);
}
else
{
Console.WriteLine("{0}使用者稽核不通過", UserName);
// 進入空閑狀态。在空閑狀态中中斷工作流。
// 不能在行為内部調用WorkflowInstance.Abort()等方法。
return ActivityExecutionStatus.Executing;
}
return ActivityExecutionStatus.Closed;
}
}
工作流運作時引擎代碼如下:
///
<summary>
/// 工作流運作時引擎類
///
</summary>
public
class Runtime:IDisposable
{
WorkflowRuntime workflowRuntime =
null;
ManualWorkflowSchedulerService manualWorkflowSchedulerService =
null;
///
<summary>
/// 初始化工作流引擎的服務與事件,并運作工作流引擎
///
</summary>
public Runtime()
{
workflowRuntime =
new WorkflowRuntime();
// 需要将SqlWorkflowPersistenceService服務的unloadOnIdle參數設定為false表示不讓工作流在空閑或解除安裝時自動持久化。
// 如果設定為true,将會在unload()執行後自動持久化工作流,這将導緻無法正常加載工作流。
workflowRuntime.AddService(new SqlWorkflowPersistenceService("server=(local);database=AuditingWorkflow;integrated security=sspi", false, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 10)));
// 添加手動排程服務
manualWorkflowSchedulerService =
new ManualWorkflowSchedulerService();
workflowRuntime.AddService(manualWorkflowSchedulerService);
workflowRuntime.WorkflowCompleted +=
delegate(object sender, WorkflowCompletedEventArgs e)
{
Console.WriteLine("{0}工作流結束", e.WorkflowInstance.InstanceId);
};
workflowRuntime.WorkflowTerminated +=
delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine("{0}工作流終止", e.WorkflowInstance.InstanceId);
};
workflowRuntime.WorkflowIdled +=
delegate(object sender, WorkflowEventArgs e)
{
e.WorkflowInstance.Abort();
Console.WriteLine("中斷了{0}工作流", e.WorkflowInstance.InstanceId);
};
workflowRuntime.WorkflowPersisted +=
new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowPersisted);
workflowRuntime.StartRuntime();
}
void workflowRuntime_WorkflowPersisted(object sender, WorkflowEventArgs e)
{
Console.WriteLine("{0}工作流持久化",e.WorkflowInstance.InstanceId);
}
///
<summary>
/// 擷取工作流排程
///
</summary>
public ManualWorkflowSchedulerService WorkflowScheduler
{
get
{
return manualWorkflowSchedulerService;
}
}
///
<summary>
/// 通過工作流類型建立工作流的執行個體
///
</summary>
///
<param name="workflowType"></param>
///
<returns></returns>
public Guid CreateWorkflow(Type workflowType)
{
WorkflowInstance instance = workflowRuntime.CreateWorkflow(workflowType);
Console.WriteLine("建立了{0}工作流", instance.InstanceId);
// 先将工作流開始,再将工作流解除安裝,這個順序不能變動。否則将在建立的時候就運作了工作流并且如果第一個稽核行為不通過,就不能正常加載了
instance.Start();
instance.Unload();
// 必須執行該語句,否則無法正常加載工作流,具體原因還不太清楚,跟蹤工作流的時候,有沒有執行該語句的工作流執行狀态是一樣的
// 初步分析是因為執行Start()方法并沒有真正的執行工作流(因為該引擎用了ManualWorkflowSchedulerService服務),直到調用RunWorkflow()方法時才執行工作流
manualWorkflowSchedulerService.RunWorkflow(instance.InstanceId);
return instance.InstanceId;
}
///
<summary>
/// 通過工作流ID加載工作流
///
</summary>
///
<param name="workflowGuid"></param>
public
void LoadWorkflow(Guid workflowGuid)
{
// 通過工作流ID擷取工作流執行個體
WorkflowInstance instance = workflowRuntime.GetWorkflow(workflowGuid);
if (instance ==
null)
return;
// 加載工作流
instance.Load();
// 通過排程服務運作工作流
manualWorkflowSchedulerService.RunWorkflow(instance.InstanceId);
}
///
<summary>
/// 資源清理
///
</summary>
public
void Dispose()
{
if (workflowRuntime !=
null)
workflowRuntime.Dispose();
}
}
用戶端代碼如下:
class Program
{
static
void Main(string[] args)
{
// 執行個體化工作流運作時引擎,該類的執行個體最好在系統初始化時執行個體化,在系統結束後執行Dispose()方法
Runtime runtime =
new Runtime();
string input =
null;
Console.Write("請輸入指令: ");
while ((input = Console.ReadLine().ToLower()) !=
"end")
{
switch (input)
{
case
"create": // 建立工作流
runtime.CreateWorkflow(typeof(BreakWorkflowAndPersistenceToDatabase.AuditingWorkflow));
break;
case
"load": // 通過工作流ID加載工作流
Console.Write("請輸入工作流ID: ");
try
{
Guid guid =
new Guid(Console.ReadLine());
runtime.LoadWorkflow(guid);
}
catch (Exception ex)
{
Console.WriteLine("加載工作流出錯!原因:{0}", ex.Message);
}
break;
}
Console.Write("請輸入指令: ");
}
}
}
執行結果如下: