工作流服務中常需啟動子流程。結合 Bookmark 實現主流程掛起/恢復與子流程生命週期管理。
基於自定義持久化表新增 ParentId 欄位標識父流程:
三節點:
public sealed class Read<TResult> : NativeActivity<TResult> {
public string BookmarkName { get; set; }
public InArgument<string> Text { get; set; }
protected override bool CanInduceIdle => true;
protected override void Execute(NativeActivityContext context) {
context.CreateBookmark(BookmarkName, Continue);
}
void Continue(NativeActivityContext context, Bookmark bookmark, object obj) {
Result.Set(context, (TResult)obj);
}
}
public sealed class CallChild : Activity {
public string FlowName { get; set; }
public CallChild() {
Implementation = new Func<Activity>(CreateBody);
}
Activity CreateBody() => new Sequence {
DisplayName = "子流程",
Activities = {
new ChildCodeActivity { FlowName = this.FlowName },
new Read<string> { BookmarkName = "CallChild" }
}
};
}
ChildCodeActivity 真正啟動子流程並寫入 ParentId:
sealed class ChildCodeActivity : CodeActivity {
public string FlowName { get; set; }
protected override void Execute(CodeActivityContext context) {
Guid childGuid = WorkFlowRun.CreateAndRun(FlowName);
var obj = InstancesTableBiz.GetInstancesTable(childGuid);
obj.ParentId = context.WorkflowInstanceId;
InstancesTableBiz.UpdateInstancesTable(obj);
}
}
兩個 Bookmark 審核節點 + 結束節點(關鍵:負責恢復父流程)。
public sealed class End : CodeActivity {
public InArgument<string> Text { get; set; }
protected override void Execute(CodeActivityContext context) {
string text = context.GetValue(Text);
Guid id = context.WorkflowInstanceId;
var obj = InstancesTableBiz.GetInstancesTable(id);
if (obj.ParentId != Guid.Empty) {
WorkFlowRun.Submit(obj.ParentId, "ParentProcess", "returnMain"); // 恢復父流程 Bookmark
}
}
}
CallChild → ChildCodeActivity 啟動子流程實例,記錄 ParentIdRead<string> (Bookmark="CallChild") 處掛起End 讀取 ParentId → WorkFlowRun.Submit 恢復父流程 Bookmark此方案經實戰驗證,歡迎提出更優方案交流。出處:https://zhuqil.cnblogs.com