如何編寫、發佈及管理 Workflow Manager 1.0 的 Workflow

 

發佈時間: 2016年5月

編寫、發佈及管理工作流程會使用 Workflow Manager API。本主題描述如何使用 Workflow Manager Client API 的方法及類別,來使用工作流程。

編寫 Workflow

在 Workflow Manager 1.0 編寫工作流程與在任何工作流程環境中編寫工作流程類似。Workflow 是使用 XAML 以宣告方式建立而成,此 XAML 定義預先定義之活動的階層。下列活動程式碼範例 (來自於自訂活動範例) 是為了在 Workflow Manager 1.0 執行而建立的宣告式工作流程。

<Activity mc:Ignorable="sap sap2010 sads" x:Class="MoviesActivityLibrary.GetMovies"
 xmlns="https://schemas.microsoft.com/netfx/2009/xaml/activities"
 xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:mca="clr-namespace:Microsoft.CSharp.Activities;assembly=System.Activities"
 xmlns:p="https://schemas.microsoft.com/workflow/2012/07/xaml/activities"
 xmlns:sads="https://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
 xmlns:sap="https://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
 xmlns:sap2010="https://schemas.microsoft.com/netfx/2010/xaml/activities/presentation"
 xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
 xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"
 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="searchKeyword" Type="InArgument(x:String)" />
    <x:Property Name="numItems" Type="InArgument(x:Int32)" />
    <x:Property Name="videoDV" Type="OutArgument(p:DynamicValue)" />
  </x:Members>
  <sap2010:ExpressionActivityEditor.ExpressionActivityEditor>C#</sap2010:ExpressionActivityEditor.ExpressionActivityEditor>
  <sap2010:WorkflowViewState.IdRef>ActivityLibrary2.Activity1_1</sap2010:WorkflowViewState.IdRef>
  <TextExpression.NamespacesForImplementation>
    <sco:Collection x:TypeArguments="x:String">
      <x:String>System</x:String>
      <x:String>System.Collections.Generic</x:String>
      <x:String>System.Data</x:String>
      <x:String>System.Linq</x:String>
      <x:String>System.Text</x:String>
      <x:String>Microsoft.Activities</x:String>
    </sco:Collection>
  </TextExpression.NamespacesForImplementation>
  <TextExpression.ReferencesForImplementation>
    <sco:Collection x:TypeArguments="AssemblyReference">
      <AssemblyReference>Microsoft.Activities</AssemblyReference>
      <AssemblyReference>Microsoft.CSharp</AssemblyReference>
      <AssemblyReference>Microsoft.Workflow.Common</AssemblyReference>
      <AssemblyReference>Microsoft.Workflow.Tracing</AssemblyReference>
      <AssemblyReference>System</AssemblyReference>
      <AssemblyReference>System.Activities</AssemblyReference>
      <AssemblyReference>System.Core</AssemblyReference>
      <AssemblyReference>System.Data</AssemblyReference>
      <AssemblyReference>System.Runtime.Serialization</AssemblyReference>
      <AssemblyReference>System.ServiceModel</AssemblyReference>
      <AssemblyReference>System.ServiceModel.Activities</AssemblyReference>
      <AssemblyReference>System.Xaml</AssemblyReference>
      <AssemblyReference>System.Xml</AssemblyReference>
      <AssemblyReference>System.Xml.Linq</AssemblyReference>
      <AssemblyReference>mscorlib</AssemblyReference>
      <AssemblyReference>MoviesActivityLibrary</AssemblyReference>
    </sco:Collection>
  </TextExpression.ReferencesForImplementation>
  <Sequence DisplayName="GetMovies" sap2010:WorkflowViewState.IdRef="Sequence_1">
    <p:HttpGet DisplayName="HttpGetFromNetflix" sap2010:WorkflowViewState.IdRef="HttpGet_1" RetryOnConnectionFailure="True">
      <p:HttpGet.ResponseContent>
        <OutArgument x:TypeArguments="p:DynamicValue">
          <mca:CSharpReference x:TypeArguments="p:DynamicValue">videoDV</mca:CSharpReference>
        </OutArgument>
      </p:HttpGet.ResponseContent>
      <p:HttpGet.Uri>
        <InArgument x:TypeArguments="x:String">
          <mca:CSharpValue x:TypeArguments="x:String">"http://odata.netflix.com/Catalog/Titles?$filter=substringof('" + searchKeyword + "', Name)&amp;$format=json&amp;$top=" + numItems + "&amp;$select=Name, Synopsis"</mca:CSharpValue>
        </InArgument>
      </p:HttpGet.Uri>
    </p:HttpGet>
    <sads:DebugSymbol.Symbol>d3dcXHNjcmF0Y2gyXHNjcmF0Y2hcZ2dvZ29sb1xCMiAtIFRlc3RcQ3VzdG9tQ29kZUFjdGl2aXRpZXNcQ3VzdG9tQ29kZUFjdGl2aXR5U2FtcGxlXE1vdmllc0FjdGl2aXR5TGlicmFyeVxHZXRNb3ZpZXMueGFtbAQxAz8OAgEBMgU9EQIBAjoLOusBAgEHNQs1XgIBAw==</sads:DebugSymbol.Symbol>
  </Sequence>
  <sap2010:WorkflowViewState.ViewStateManager>
    <sap2010:ViewStateManager>
      <sap2010:ViewStateData Id="HttpGet_1" sap:VirtualizedContainerService.HintSize="284,120" />
      <sap2010:ViewStateData Id="Sequence_1" sap:VirtualizedContainerService.HintSize="306,244">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
      </sap2010:ViewStateData>
      <sap2010:ViewStateData Id="ActivityLibrary2.Activity1_1" sap:VirtualizedContainerService.HintSize="346,324" />
    </sap2010:ViewStateManager>
  </sap2010:WorkflowViewState.ViewStateManager>
</Activity>

下列螢幕擷取畫面顯示了已在 Visual Studio 2012 中開啟的工作流程。

GetMovies Workflow

此範例中的工作流程會根據搜尋參數從公開 Web 服務擷取影片資訊。這些參數會定義為內容 (搜尋關鍵字及記錄計數)。接著,工作流程會傳回已擷取的資訊做為 DynamicValue,讓呼叫者將傳回的資料當做屬性包來處理。

發佈 Workflow

使用 Workflow Manager 主控的工作流程必須先發行至範圍。已使用 WorkflowManagementClient 與範圍進行互動。以下程式碼範例示範如何針對此範例目的建立工作流程範圍。

var rootClient = new WorkflowManagementClient(new Uri(rootScope));

            return rootClient.CurrentScope.PublishChildScope(scopeName,
                new ScopeDescription()
                {
                    UserComments = string.Format("For {0} sample only", scopeName)
                });

建立了範圍之後,即可將工作流程發佈至範圍。已使用 ActivityDescription 將所有 XAML 文件上傳為活動。接著,會透過 WorkflowDescription 給予工作流程相關聯的中繼資料。以下程式碼範例示範如何發行工作流程和其相對應的活動。

// publish the activity description related with the workflow
client.Activities.Publish(
new ActivityDescription(WorkflowUtils.Translate(xamlFilePath)) { Name = workflowName });

// now, publish the workflow description
WorkflowDescription description = new WorkflowDescription
{
Name = workflowName,
ActivityPath = workflowName,
// additional properties elided for simplicity
};

// publish!
client.Workflows.Publish(description);

管理工作流程

一旦工作流程發行至 Workflow Manager,系統就會加以執行,並且能夠擷取其狀態。下列程式碼範例示範如何執行已發佈的工作流程。啟動工作流程會使用 T:Microsoft.Workflow.Client.WorkflowStartInfo 物件來儲存啟動資訊,作法與處理程序使用 StartInfo 物件的方式類似。

Console.Write("Starting workflow instance...");
WorkflowStartParameters startParameters = new WorkflowStartParameters();
startParameters.Content.Add("Title", "Titanic");
startParameters.Content.Add("NumberOfMovies", 3);
string instanceId = client.Workflows.Start(workflowName, startParameters);

下列程式碼範例示範如何查詢執行中工作流程的狀態。狀態會以字串的形式傳回。

WorkflowInstanceInfo instanceInfo = client.Instances.Get(workflowName, instanceId);
currentStatus = instanceInfo.UserStatus;

if (instanceInfo.WorkflowStatus == WorkflowInstanceStatus.Completed)
{
    Console.WriteLine("\nWorkflow instance completed");
}