使用長期雙向訊息交換的父子工作流程模式
針對長時間執行的複雜程序實作工作流程常用的設計方法是,識別可隔離成較小、較簡單且可重複使用之工作流程的商務邏輯部分,然後從主要工作流程協調各部分的執行。例如,進行訂單處理時,您可能會選擇將出貨邏輯定義為 (子) 工作流程,之後可在必要時,讓主要訂購單 (父) 工作流程呼叫。
在 .NET Framework 4 的 Windows Workflow Foundation 中,沒有內建功能可從某個長時間執行的工作流程「呼叫」另一個長時間執行的工作流程。不過,有一些實作選項可讓開發人員手動設定此行為。此範例不討論所有可用選項;而是著重於其中一個最常用的一般方法,實作「呼叫工作流程」模式 - 長期雙向交換訊息,而明確來說是在長時間執行的 WCF 工作流程服務 (XAMLX 工作流程) 中。長期雙向交換訊息模式背後的概念很簡單 - 父工作流程呼叫由子工作流程公開的端點,並傳遞內容權杖 (用於相互關聯)、回呼位址與要求訊息。經過一段時間後,當子工作流程完成時,就會回呼父工作流程,通知其已完成執行。
如需手動設定長期雙向訊息交換的詳細資訊,請參閱有關長期雙向訊息交換 (https://go.microsoft.com/fwlink/?LinkId=196632) (可能為英文網頁) 的 MSDN 文章,以及相關的 WF 範例長期雙向訊息交換範例 (https://go.microsoft.com/fwlink/?LinkId=194430) (可能為英文網頁),以及作法:建立呼叫另一個工作流程服務的工作流程服務。
此範例的主要目標是以 IActivityTemplateFactory 介面為基礎提供兩種自訂活動,以及設計成透過自動化設定程序來簡化長期雙向訊息交換實作。子工作流程中會使用Workflow Callable Sequence活動,而不是建立工作流程時產生的預設「接收」與「傳送」活動。父工作流程中會使用Call Workflow Sequence活動,以產生活動與必要的相關組態來和子工作流程通訊。這些活動都可以重複使用,並能新增至 Visual Studio 工具箱。
範例包含兩個方案:
第一個方案 (CallWorkflowActivities) 包含上述的兩個活動。為了讓這些活動能在「Visual Studio 工作流程設計工具」中使用,您必須編譯方案並將活動從產生的組件新增至 Visual Studio 工具箱。
第二個方案 (DurableDuplex_with_CallWorkflowActivities) 使用透過Workflow Callable Sequence與Call Workflow Sequence活動設定之長期雙向訊息交換,來實作父工作流程與子工作流程通訊。
注意
提供的範例僅適用於教學用途。請勿將範例用於生產環境,因為這些範例並未在生產環境中測試。Microsoft 不對這些範例提供技術支援。
必要條件
此範例應用程式的適用對象是具有下列知識水準的使用者:
對於 Internet Information Services (IIS) 有基本了解
對於 WCF 與 Windows Workflow Foundation (WF) 應用程式有基本了解
對於 Windows PowerShell 有基本了解
對於 Microsoft SQL Server 有基本了解
此外,必須已安裝 Microsoft AppFabric 1.1 for Windows Server 的「主控服務」執行階段功能並設定下列功能,才能執行 DurableDuplex_with_CallWorkflowActivities 解決方案:
持續性儲存區
監控儲存區
範例應用程式位置與檔案
方案 1:CallWorkflowActivities
檔案名稱 | 描述 |
---|---|
CallWorkflowActivities.sln |
CallWorkflowActivities 方案的方案檔案 |
CallWorkflowActivities |
專案資料夾 |
CallWorkflowActivities.csproj |
專案檔 |
Properties\AssemblyInfo.cs |
組件資訊檔 |
Activities\WorkflowCallableSequence.cs、Activities \CallWorkflowService.cs |
兩個 IActivityTemplateFactory 活動的原始程式檔 - WorkflowCallableSequence 與 CallWorkflowService |
UI\CallWorkflowConfiguration.xaml、UI\CallWorkflowConfiguration.xaml.cs、UI\WebConfigContent.xaml、UI\WebConfigContent.xaml.cs、UI\WorkflowCallableSequenceConfiguration.xaml、UI\WorkflowCallableSequenceConfiguration.xaml.cs |
用於設定長期雙向訊息交換的對話方塊 UI 設計與原始程式檔 |
Code\Helpers.cs |
含有支援類別的原始程式碼 |
Images\requiredBang.gif |
必要欄位的影像檔案 |
方案 2:DurableDuplex_with_CallWorkflowActivities
檔案名稱 | 描述 |
---|---|
DurableDuplex_with_CallWorkflowActivities.sln |
DurableDuplex_with_CallWorkflowActivities 方案的方案檔案 |
SampleChildService |
範例子服務的專案資料夾 |
SampleChildService.csproj |
範例子服務的專案檔 |
Properties\AssemblyInfo.cs |
組件資訊檔 |
ChildWorkflow.xamlx |
子服務工作流程定義 (XAMLX) |
Web.config |
子服務的 Web 組態檔 |
SampleParentService |
範例父服務的專案資料夾 |
SampleParentService.csproj |
範例父服務的專案檔 |
Properties\AssemblyInfo.cs |
組件資訊檔 |
ParentWorkflow.xamlx |
父服務工作流程定義 (XAMLX) |
Web.config |
父服務的 Web 組態檔 |
SampleClient |
測試用戶端的資料夾 |
SampleClient.csproj |
測試用戶端專案檔 |
mainForm.cs、mainForm.Designer.cs、mainForm.resx、Program.cs |
主表單與應用程式的原始程式檔 |
Properties\Resources.Designer.cs、Properties\Resources.resx、Properties\Settings.Designer.cs、Properties\Settings.settings |
資源相關檔案與專案設定 |
Properties\AssemblyInfo.cs |
組件資訊檔 |
app.config |
測試用戶端的應用程式設定檔 |
設定此範例
以系統管理權限啟動 Visual Studio 2010。
注意
這些步驟示範如何使用 Visual Studio 2010 來建置和部署 CallWorkflowActivities 與 DurableDuplex_with_CallWorkflowActivities 方案,以及如何設定應用程式集區以搭配這些服務使用。
開啟 <samples>\ Samples\Integration\Call Workflow (DurableDuplex)\ CallWorkflowActivities\CallWorkflowActivities.sln,其中 <samples> 是您安裝 AppFabric 範例的路徑。
在 [建置] 功能表上,按一下 [建置方案]。確定輸出視窗中的專案已順利建置,而且沒有錯誤。
注意
現在具有 WorkflowCallableSequence 與 CallWorkflowService 活動的組件已完成編譯,且準備好可以新增至工具列 (如需詳細資訊,請參閱<執行此範例>一節)。
開啟 <samples>\ Samples\Integration\Call Workflow (DurableDuplex)\DurableDuplex_with_CallWorkflowActivities\ DurableDuplex_with_CallWorkflowActivities.sln,其中 <samples> 是您安裝 AppFabric 範例的路徑。
當您收到為 SampleParentService 與 SampleChildService 專案建立虛擬目錄的提示時,請按一下 [是]。
在 [建置] 功能表上,按一下 [建置方案]。確定輸出視窗中三個專案都已順利建置,而且沒有錯誤。
啟動 Internet Information Services (IIS) 管理員:依序按一下 [開始]、[所有程式] 及 [Microsoft AppFabric 1.1 for Windows Server],然後按一下 [Internet Information Services (IIS) 管理員]。
展開左邊樹狀檢視中的伺服器節點,然後按一下 [應用程式集區]。
在清單中即將執行範例服務的集區上按一下滑鼠右鍵 (您可以使用現有的集區或建立新的集區),然後選取 [進階設定]。
使用下拉式選項將 [.NET Framework 版本] 設定為 v4.0,然後按一下 [確定]。
在左窗格中,展開 [網站],然後展開 [預設的網站]。
尋找 SampleChildService 應用程式,在該應用程式上按一下滑鼠右鍵並選取 [管理應用程式],然後選取 [進階設定]。
將 [已啟用的通訊協定] 屬性從 http 更新為 http,net.pipe。*請注意,逗號後面沒有空格。*按一下 [確定] 確認變更。
在 [應用程式集區] 屬性中,瀏覽以選取在步驟 9 中設定的應用程式集區。
尋找 SampleParentService 應用程式,在該應用程式上按一下滑鼠右鍵並選取 [管理應用程式],然後選取 [進階設定]。
將 [已啟用的通訊協定] 屬性從 http 更新為 http,net.pipe。*請注意,逗號後面沒有空格。*按一下 [確定] 確認變更。
在 [應用程式集區] 屬性中,瀏覽以選取在步驟 9 中設定的應用程式集區。
注意
步驟 13 至步驟 16 會將管理持續性工作流程執行個體所需的 net.pipe 通訊協定新增至父服務與子服務應用程式。
執行此範例:選項 1
以系統管理權限啟動 Visual Studio 2010。
重要
執行此範例的選項有兩種,本主題提供執行這兩種選項的步驟。選項 1 逐步解說端對端經驗,它使用 WorkflowCallableSequence 與 CallWorkflowService 活動從父工作流程呼叫子工作流程,而選項 2 只會查看最終的方案:準備執行的長期雙向訊息交換實作,完全略過設計體驗。如需詳細資訊,請參閱以下的<示範>一節。
注意
CallWorkflowActivities 方案是為了加強實作長期雙向訊息交換的設計階段體驗而設計。就這一點而論,並無項目可供「執行」。不過,這些步驟提供使用簡單方案中之活動的逐步解說,其中父工作流程會呼叫子工作流程。
建立「WCF 工作流程服務應用程式」類型 (此專案範本位於 [工作流程] 專案類型下) 的新專案,然後將新專案命名為 ChildService。
將範例自訂活動新增至工具箱:當 WF 設計工具開啟時,在工具箱的 [傳訊] 活動群組上按一下滑鼠右鍵。
選取 [選擇項目],然後按一下 [System.Activities 元件] 索引標籤。
按一下 [瀏覽],然後瀏覽至 <samples>\ Samples\Integration\Call Workflow (DurableDuplex)\ CallWorkflowActivities\ CallWorkflowActivities\bin\Debug。選取 CallWorkflowActivities.dll 組件,然後按一下 [開啟] (這是本文<設定此範例>一節的步驟 3 中所編譯的組件)。您會在 [System.Activities 元件] 清單頂端注意到有兩個新項目。
按一下 [確定],以將 CallWorkflowService 與 WorkflowCallableSequence 活動新增至工具箱。您的工具箱看起應該像下列螢幕擷取畫面這樣。
實作 ChildService 工作流程:在 [方案總管] 中,將 Service1.xamlx 重新命名為 ChildService.xamlx。
在 ChildService 的主設計工具區域中,選取 [循序服務] 活動,然後按下 Delete。
將 WorkflowCallableSequence 活動從工具箱拖曳至 WF 設計工具介面。這樣會開啟設定對話方塊,引導您將 ChildService 設定為長期雙向訊息交換的參與者。
設定 WorkflowCallableSequence:填入屬性 (如下列螢幕擷取畫面所示),然後按一下 [確定]。
更新 web.config 檔案:長期雙向訊息交換實作的運作情況取決於 web.config 項目是否正確。[Web.config 更新] 畫面會自動產生子工作流程的 web.config 檔案所需的項目。
注意
web.config 檔案本身不會自動更新。在下一個步驟中,您會複製必要的項目並貼入 web.config 檔案。
按一下 [複製到剪貼簿並關閉]。如此就會將反白顯示的必要項目複製到剪貼簿,準備貼入 web.config 檔案。按一下訊息方塊中的 [確定]。
開啟 ChildService 專案的 web.config 檔案,然後在 <system.serviceModel> 標記後面貼上剪貼簿內容 (來自步驟 12):
... <system.serviceModel> <services> <service name="ChildService"> <endpoint address="" binding="wsHttpContextBinding" contract="ICallChildService" name="ChildServiceICallChildServiceStartWorkflow" /> </service> </services> <client> <endpoint binding="wsHttpContextBinding" contract="ICallChildService" name="ChildServiceICallChildServiceWorkflowCompleted" /> </client> <behaviors> ...
完成 ChildService 實作:為求簡明,我們在此工作流程的本文中,只會將要求的值指派給回應 (兩者預設均為字串;不過在實際的實作中,可針對資料合約更新這些值)。
將 [延遲] 活動從工具箱拖曳至 [本文] 順序。使用下列屬性設定 [延遲] 活動:Duration = New TimeSpan(0, 2, 0)。
將 [指派] 活動從工具箱拖曳至 [本文] 順序,放在 [延遲] 順序後面。使用下列屬性設定 [指派] 活動:To = response; Value = request。
儲存專案。
啟用 IIS/WAS 主控服務:若要設定可在 IIS/WAS 與 AppFabric 中主控的工作流程,請在 [方案總管] 中的 [ChildService 專案] (而非解決方案) 上按一下滑鼠右鍵,然後選取 [內容]。
選取第三個設定頁面 ([Web]),然後選取 [伺服器] 區段中的 [使用本機 IIS Web 伺服器]。按一下 [建立虛擬目錄],然後按一下快顯訊息方塊中的 [確定]。儲存專案。
建立 ParentService 工作流程:在 [方案總管] 中的方案 (而非專案) 上按一下滑鼠右鍵,然後選取 [新增 - > 新增專案]。選取 [WCF 工作流程服務應用程式] 做為專案類型,然後將新專案命名為 ParentService。按一下 [確定]。
在 [方案總管] 中,將 Service1.xamlx 重新命名為 ParentService.xamlx。
將 [CallWorkflowService] 活動從工具箱拖曳至 WF 設計介面,直接放在 [SendResponse] 活動後面。這樣會開啟 CallWorkflowService 的設定對話方塊。
使用省略符號按鈕 ([…]),瀏覽到已在先前步驟中建立的 ChildService.xamlx 工作流程定義,然後選取 [wsHttpContextBinding],以符合在步驟 10 選取的通訊協定。設定視窗看起來應該像下列螢幕擷取畫面。
注意
所有要求/回應服務合約與操作名稱已從子服務定義中自動探索。
按一下 [確定]。
更新 web.config 檔案:隨即開啟 [Web.config 更新] 對話方塊,其中包含連線到子服務所需的項目。請注意,需要輸入實際的子端點位址與回呼端點位址。
按一下 [複製到剪貼簿並關閉]。這樣會將反白顯示的 web.config 項目複製到剪貼簿,準備貼入 web.config 檔案。按一下快顯訊息方塊中的 [確定]。
開啟 ParentService 專案的 web.config 檔案,然後將剪貼簿的內容直接貼到 <system.serviceModel> 元素後面。
注意
請注意 XML 中的重要註解 – 父服務也需要公開端點,以供其用戶端使用。為了達到此範例的目的,您可以使用範例 <endpoint> (定義為註解的一部分)。web.config 檔案看起來應如下所示:
... <system.serviceModel> <services> <service name="Service1"> <endpoint address="" binding="basicHttpBinding" contract="IService" /> <endpoint address="ChildCallback" binding="wsHttpContextBinding" contract="ICallChildService" name="Service1ICallChildServiceWorkflowCompleted" /> </service> </services> <client> <endpoint address="https://localhost/ChildService/ChildService.xamlx" binding="wsHttpContextBinding" bindingConfiguration="Service1ICallChildService_InitCallback" contract="ICallChildService" name="Service1ICallChildServiceStartWorkflow" /> </client> <bindings> <wsHttpContextBinding> <binding name="Service1ICallChildService_InitCallback" clientCallbackAddress="https://localhost/ParentService/ParentService.xamlx/ChildCallback" /> </wsHttpContextBinding> </bindings> <behaviors> <serviceBehaviors> ...
完成 ParentService 實作:父工作流程需要將服務呼叫的參數值傳遞給子服務。
若要將值指派給要求,請將 [指派] 活動從工具箱拖曳至 [呼叫工作流程] 順序,放在 [傳送要求] 活動前面。使用下列屬性設定 [指派] 活動:To = request; Value = data.ToString
儲存專案。
啟用 IIS/WAS 主控的 ParentService:若要設定可在 IIS/WAS 與 AppFabric 中主控的工作流程,請在 [方案總管] 中的 [ParentService 專案] (而非解決方案) 上按一下滑鼠右鍵,然後選取 [內容]。
選取第三個設定頁面 ([Web]),然後選取 [伺服器] 區段中的 [使用本機 IIS Web 伺服器]。按一下 [建立虛擬目錄],然後按一下快顯訊息方塊中的 [確定]。儲存專案。
建置方案。
設定 IIS/WAS 以主控 ParentService 與 ChildService 長期服務:啟動 Internet Information Services (IIS) 管理員:依序按一下 [開始]、[所有程式] 及 [Microsoft AppFabric 1.1 for Windows Server],然後按一下 [Internet Information Services (IIS) 管理員]。
在左窗格中,展開 [網站],然後展開 [預設的網站]。
尋找 ChildService 應用程式,在該應用程式上按一下滑鼠右鍵並選取 [管理應用程式],然後選取 [進階設定]。
將 [已啟用的通訊協定] 屬性從 http 更新為 http,net.pipe *(請注意,逗號後面沒有空格)。*按一下 [確定] 確認變更。
尋找 ParentService 應用程式,在該應用程式上按一下滑鼠右鍵並選取 [管理應用程式],然後選取 [進階設定]。
將 [已啟用的通訊協定] 屬性從 http 更新為 http,net.pipe *(請注意,逗號後面沒有空格)。*按一下 [確定] 確認變更。
執行 WCFTestClient 以啟動父工作流程執行個體。執行下列命令來執行 WCF 測試用戶端應用程式:C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe (對於 32 位元平台) 或 "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe" (對於 64 位元平台)。
選取 [新增] -> [新增服務] 以新增父服務的參考 - https://localhost/ParentService/ParentService.xamlx。
在新增參考之後,按兩下 [GetData()] 方法,然後在左窗格中輸入 123 做為 int 參數值。按一下 [叫用]。
使用「AppFabric 儀表板」來檢查 ParentService 與 ChildService 執行個體的狀態。您將會注意到,因為父服務收到子服務的完成通知,所以在 ChildService 完成之後,父服務也會隨即完成。
執行此範例:選項 2
以系統管理權限啟動 Visual Studio 2010。
重要
執行此範例的選項有兩種,本主題提供執行這兩種選項的步驟。選項 1 逐步解說端對端經驗,它使用 WorkflowCallableSequence 與 CallWorkflowService 活動從父工作流程呼叫子工作流程,而選項 2 只會查看最終的方案:準備執行的長期雙向訊息交換實作,完全略過設計體驗。如需詳細資訊,請參閱以下的<示範>一節。
開啟 <samples>\ Samples\Integration\Call Workflow (DurableDuplex)\DurableDuplex_with_CallWorkflowActivities\ DurableDuplex_with_CallWorkflowActivities.sln,其中 <samples> 是您安裝 AppFabric 範例的路徑。
請確定已將 SampleClient 設定為啟始專案 (在 [SampleClient] 專案上按一下滑鼠右鍵,然後按一下 [設定為啟始專案])。
按 F5 以執行範例。將會啟動範例測試用戶端應用程式。
按一下 [Call Parent Service] (呼叫父服務)。
檢視 [Workflow Instances] (工作流程執行個體) 文字。它會顯示父工作流程與子工作流程的開始/完成事件。在此範例中,父工作流程會使用 ParallelForEach 活動,同時啟動子服務的三個執行個體,並在三個子服務完成之後,隨即完成。您也可以使用「AppFabric 儀表板」來追蹤執行中的父/子服務執行個體。
注意
子工作流程會在啟動之後,進入休眠狀態兩分鐘。在這段期間,所有父執行個體與子執行個體都會進入閒置模式,並儲存至持續性儲存區。經過兩分鐘之後,就會發生完成事件。
移除此範例
啟動 Internet Information Services (IIS) 管理員:依序按一下 [開始]、[所有程式] 及 [Microsoft AppFabric 1.1 for Windows Server],然後按一下 [Internet Information Services (IIS) 管理員]。
展開左邊樹狀檢視中的伺服器節點。展開 [網站],然後展開 [預設的網站]。
按一下 [SampleChildService] 節點,然後按下 [移除]。
按一下 [是] 確認移除選取的應用程式。
按一下 [SampleParentService] 節點,然後按下 [移除]。
按一下 [是] 確認移除選取的應用程式。
如果您已依照<執行此範例>下選項 1 的指示進行,您還需要:
按一下 [ChildService] 節點,然後按下 [移除]。
按一下 [是] 確認移除選取的應用程式。
按一下 [ParentService] 節點,然後按下 [移除]。
按一下 [是] 確認移除選取的應用程式。
示範
執行此範例的選項有兩種,本主題提供執行這兩種選項的步驟。採用選項 1 優於選項 2,因為選項 1 逐步解說端對端經驗,它使用 WorkflowCallableSequence 與 CallWorkflowService 活動從父工作流程呼叫子工作流程,這也是此範例的主要目標。選項 2 只會查看最終的方案 - 準備執行的長期雙向訊息交換實作,完全略過設計體驗。
<執行此範例>下的選項 1 示範如何使用專案中的兩個自訂活動。
首先,建立子工作流程服務;刪除預設的「循序服務」活動,然後以 WorkflowCallableSequence 活動取代。WorkflowCallableSequence 是活動範本工廠,它會根據使用者輸入來產生和設定傳訊活動 (「接收」與「傳送」),以便支援回呼相互關聯。回呼相互關聯的必要條件如下:要求內容必須包含用於相互關聯回父工作流程的唯一內容權杖,而且必須包含用於傳送完成通知的回呼位址。「接收」活動會初始化輸入要求的回呼相互關聯控制代碼,而「傳送」活動會遵循該控制代碼的指示,依據初始要求中傳遞的動態回呼位址,將完成通知傳回給父工作流程。
WorkflowCallableSequence 邏輯也會為服務產生 web.config 項目、服務與用戶端端點,以及任何必要的繫結項目。
下一個步驟會建立父工作流程服務。CallWorkflowService 活動範本工廠會提示您輸入子服務定義、檢查其設定,並據此產生與子服務進行長期雙向訊息交換之通訊所需的傳訊活動 (「傳送」與「接收」)。「傳送」活動會初始化回呼相互關聯 (邏輯上,此步驟會產生唯一內容權杖,然後連同要求一起傳遞給子工作流程),然後「接收」活動會使用相同的內容權杖,來與從子工作流程送回的完成通知關聯 (透過與「傳送」活動所初始化的相互關聯控制代碼關聯)。
CallWorkflowService 邏輯也會為服務產生 web.config 項目、服務與用戶端端點,以及任何必要的繫結項目。注意自訂繫結組態的定義中使用的 clientCallbackAddress 屬性。這就是要送至用戶端的要求訊息中所要包含的位址,如此才會動態地轉送回正確的呼叫者 (在此案例中為父工作流程)。
<執行此範例>下的選項 2 透過使用子工作流程中的 WorkflowCallableSequence 與父工作流程中的 CallWorkflowService 來實作,提供準備執行的長期雙向訊息交換方案。
用戶端呼叫父服務,接著父服務會使用 ParallelForEach 活動來同時啟動子服務的三個執行個體。子服務在收到來自父服務的初始訊息之後,會進入休眠模式兩分鐘 (使用「延遲」活動),然後在這段時間過後,子服務會將完成通知傳回給父服務。只有當子服務的所有執行個體均已完成時,父服務才會完成。父服務與子服務執行個體都會將項目記錄至「應用程式」事件記錄檔,而且會使用 "Samples" 做為事件來源。用戶端 UI 會監控此事件來源的「應用程式」事件記錄檔,以在 [工作流程執行個體] 文字方塊中顯示完成事件。
2012-03-05