首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

WF 動態更新核心觀念與實作步驟(一):何時能更新、如何驗證、完整範例

     編輯:關於C語言

什麼是動態更新?

Windows Workflow Foundation (WF) 的動態更新允許在工作流實例執行期間修改其結構:新增/刪除活動、變更屬性、調整規則條件。關鍵特性:

  • 僅影響目前執行中的實例
  • 原始工作流定義與未來實例完全不受影響
  • 無需重新編譯、重新部署、重新啟動工作流

何時可以進行動態更新?

WF 執行緒為單一執行緒模型,為避免競態條件,僅允許在以下三種狀態執行更新:

  1. 工作流實例建立完成,尚未啟動 → WorkflowRuntime.WorkflowCreated 事件
  2. 工作流處於暫停狀態 → WorkflowRuntime.WorkflowSuspended 事件(可用 SuspendActivity 觸發)
  3. 工作流處於閒置狀態 → WorkflowRuntime.WorkflowIdled 事件(DelayActivity、HandleExternalEventActivity 會進入閒置)

動態更新標準五步驟

  1. 建立 WorkflowChanges:傳入根活動(宿主端用 GetWorkflowDefinition(),內部用 this)
  2. 操作暫時工作流複本:透過 TransientWorkflow 屬性取得複本,使用 GetActivityByName 或 Activities 集合尋找父活動
  3. 修改活動結構:Add、Insert、Remove 方法新增/插入/移除活動
  4. 驗證變更:呼叫 Validate(),檢查 ValidationErrorCollection
  5. 套用變更:宿主端呼叫 WorkflowInstance.ApplyWorkflowChanges(),內部呼叫 this.ApplyWorkflowChanges()

阻止動態更新:DynamicUpdateCondition

在工作流設計器中設定 DynamicUpdateCondition 屬性(型別為 RuleConditionReference 或程式碼條件)。評估為 false 時,ApplyWorkflowChanges 會拋出 InvalidOperationException。

完整範例:主控台應用程式

工作流定義

public sealed partial class CaryDynamicUpdateWorkflow : SequentialWorkflowActivity
{
    public CaryDynamicUpdateWorkflow() { InitializeComponent(); }

    private void beforeSequence_ExecuteCode(object sender, EventArgs e)
    { Console.WriteLine("beforeSequence執行了"); }

    private void afterSequence_ExecuteCode(object sender, EventArgs e)
    { Console.WriteLine("afterSequence執行了"); }

    private void IsUpdate(object sender, ConditionalEventArgs e)
    { e.Result = true; } // 條件永真,觸發動態更新
}

自訂活動:PrintActivity

public partial class PrintActivity : Activity
{
    public PrintActivity() { InitializeComponent(); }

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext context)
    {
        Console.WriteLine("自定義 Print活動");
        return base.Execute(context);
    }
}

宿主程式程式碼

class Program
{
    static void Main()
    {
        using (WorkflowRuntime runtime = new WorkflowRuntime())
        {
            runtime.WorkflowCreated += Runtime_WorkflowCreated;
            WorkflowInstance instance = runtime.CreateWorkflow(typeof(CaryDynamicUpdateWorkflow));
            instance.Start();
            Console.ReadLine();
        }
    }

    static void Runtime_WorkflowCreated(object sender, WorkflowEventArgs e)
    {
        WorkflowChanges wc = new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());
        CompositeActivity container = wc.TransientWorkflow.GetActivityByName("sequenceActivityContainer") as CompositeActivity;
        
        if (container != null)
        {
            container.Activities.Add(new PrintActivity());
            ValidationErrorCollection errors = wc.Validate();
            if (errors.Count == 0)
            {
                try { e.WorkflowInstance.ApplyWorkflowChanges(wc); }
                catch (Exception ex) { Console.WriteLine($"異常:{ex.Message}"); }
            }
        }
    }
}

執行流程圖解

工作流設計器圖示

設計器中 sequenceActivityContainer 為 SequenceActivity,動態更新時將 PrintActivity 插入其子活動集合。

常見錯誤與除錯技巧

  • 驗證失敗:檢查活動名稱拼寫、父活動是否為 CompositeActivity、屬性繫結是否完整
  • ApplyWorkflowChanges 擲出例外:確認工作流處於允許更新的三種狀態之一
  • 變更未生效:確認是否對 TransientWorkflow 操作而非原始定義
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved