第六章核心主題:長時間運行工作流的資源管理——實例卸載/載入與 SQL 持久化。涵蓋卸載時機、手動/自動持久化、SqlWorkflowPersistenceService 設定、資料庫腳本部署、Windows Forms 測試應用與主控台自動持久化範例。
長時間工作流(等待人工審核、外部系統回應)若常駐記憶體,會耗盡伺服器資源。WF 提供機制將空閒實例序列化至 SQL Server,釋放資源;稍後自動或手動重新載入繼續執行。亦可防止系統異常關機導致實例遺失。
ActivityExecutionContext 完成結束時。Delay、等待外部事件)。TransactionScopeActivity 完成時(第 15 章)。[PersistOnCloseAttribute] 完成時。WorkflowInstance.Unload() 或 TryUnload()。可插拔服務,協同 WorkflowInstance 執行儲存/還原。支援多進程/多機器共享單一資料庫,儲存實例狀態(阻塞、執行中、空閒)、序列化資料、擁有者識別等。
WorkflowInstance 三大持久化方法:
| 方法 | 行為 |
|---|---|
| Load | 載入先前卸載的實例 |
| TryUnload | 嘗試非阻塞式卸載,立即回傳 bool 表示是否成功 |
| Unload | 同步阻塞式卸載,直到持久化完成 |
WorkflowStore。%WINDIR%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\ZH-CHS\SqlPersistence.Schema.sql 建立資料表/檢視。SqlPersistence.Logic.sql 建立預存程序。
UI 三按鈕:Start/Unload/Load。工作流包含兩個 Code 活動,第一個 Thread.Sleep(10秒) 模擬長時間處理,期間點擊 Unload 觸發持久化,Load 重新載入續跑。
WorkflowPersister WinForms 專案,加入 app.config 連線字串。WorkflowFactory 註冊 SqlWorkflowPersistenceService(連線字串)。Load 事件初始化 Runtime 並訂閱 Completed/Terminated 事件。_instance.Unload();Load 按鈕呼叫 _instance.Load()。InvokeRequired/BeginInvoke 確保跨執行緒 UI 更新安全。PersistedWorkflow:兩 Code 活動記錄開始/結束時間與耗時。

測試結果:未卸載實例耗時 ~10 秒;卸載後重載實例耗時 ~1 分 41 秒(含資料庫輪詢),InstanceState 表記錄相同 InstanceID,驗證持久化成功。
利用 Delay 活動觸發自動持久化。關鍵在於 SqlWorkflowPersistenceService 建構子傳入 NameValueCollection 設定 UnloadOnIdle=true。
NameValueCollection parms = new NameValueCollection();
parms.Add("UnloadOnIdle", "true");
parms.Add("ConnectionString", connStr);
_workflowRuntime.AddService(new SqlWorkflowPersistenceService(parms));
工作流:Code → Delay(30秒) → Code。執行時,Delay 期間實例自動持久化至資料庫,30 秒後(最多 2 分鐘輪詢間隔)自動載入繼續。

進階設定:四參數建構子可調整鎖定逾時、資料庫輪詢頻率(預設 2 分鐘),平衡響應速度與資料庫負載。