自訂活動(五)中止活動的運行
無論用停止、放棄、中止或中斷等之類的這些詞都不能很直接地表達我這裡所表達的意思!這是目前為止我遇到的封裝商務邏輯到自訂活動的最大障礙;因為就自訂審核活動來講,使用者所設計的工作流程中每一個活動可能被多次執行。例如需要多個人蔘與同一個層次的審核,當條件不滿足是便“停止”運行,然後等待下一個使用者來輸入用於計算的基礎資料,並重新執行該邏輯,直到條件滿足該活動執行完畢並過渡到下一個活動為止。需要特別說明一下,這裡的自訂活動的邏輯包含了基礎資料的讀取,條件的判斷及是否往下執行、原地等待還是回退的處理,而不是用一大堆WF預置的活動來支援,全部功能都封裝於一個活動之內;另外這裡不對回退進行說明,有關回退的內容請看後續的文章。
在WF的SDK中有一個很關鍵的術語“persistence
point”,它決定了下次載入時WF執行個體開始啟動並執行點。我將用這個詞語來解釋一些問題,讓我們來看一下它在我們“中斷”工作流程中所產生的影響!
我們嘗試過多種方法去“中斷”WF執行個體的運行,如:
- 殺死線程或進程。此方法可以使WF執行個體被再次載入並重新執行被中斷的活動的邏輯。但此方法在實際應用中不可取,有很多的負面影響。
- 調用WorkflowInstance.Abort。此方法的結果是不確定的,先放著下面會描述。
- 調用WorkflowInstance.Terminate,此方法行不通,會將WF執行個體從資料庫中清除出去!!!
- 調用WorkflowInstance.Unload,此方法也行不能,該方法會先進行持久化,然後再“中止”WF執行個體的運行。因為“persistence point”位於活動的中間邏輯——請求“中斷”的後面,所以導致WF執行個體不能載入運行!!!
- 在活動執行邏輯內部產生異常,此方法我們是沒有成功過,最終結果也是將WF執行個體從資料庫中清除出去!!!
大家已經知道突破點在於Abort上,但這個也被我們差一點放棄,具體的過程已經想不太清楚了,好象是在活動執行邏輯中不能直接調用WF執行個體的Abort方法,只能由引擎來進行此處理才可以。如何將活動的控制權微妙地轉交到引擎上去,我的同事許道松花了一些工夫:)。解決的方法是在活動執行邏輯中返回Executing狀態,這樣就會觸發引擎的OnIdel事件,然後在引擎的OnIdel事件處理中調用WF執行個體的Abort方法。然而問題不是到此就結束了。
我們用SqlWorkflowPersistenceService來進行我們的持久化工作,在它的建構函式裡有一個unloadOnIdle參數,就是這個參數給我們帶來了不小的麻煩。如果該參數為真,則會在引擎的OnIdel事件中調用WF執行個體的Unload方法,這樣就會形成一個髒的“persistence point”。所以必須將該參數置為False。
至此同一個活動可重複執行的問題得到瞭解決。至此自訂活動的話題也將結束。下面將針對自訂審核活動特有的設計進行說明,待續!