程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 工作流編程循序漸進(4:InvokeWorkflowActivity活動)(5)

工作流編程循序漸進(4:InvokeWorkflowActivity活動)(5)

編輯:關於C語言

六、定義在工作流實例與宿主間通信的本地服務

WWF中的服務可分為核心服務和本地服務。核心服務由WF定義,而本地服務(也稱為數據交換服務) 則是開發人員自定義的。本地服務可以是任何想在WF中實現的服務,一個通常的用處是使用本地服務在工作流實例與宿主之間進行通信。有關於“本地服務”的全面討論是一個復雜的話題,我想在本系列後面的學習教程中對之展開全面深入的探討,在此不贅述。

[一]定義接口

根據WWF中本地服務的定義要求,首先要定義一個修飾以ExternalDataExchange屬性的接口,我們對之命名為ILocalService,代碼如下:

[ExternalDataExchange]
internal interface ILocalService
{
 event EventHandler<ExternalDataEventArgs> InvokedWorkflowComplete;
 void WorkComplete(Guid HostWFGuid);
}

[二]創建本地服務類

然後,基於上述接口創建一個本地服務類,代碼如下:

//定義一個本地服務實現,該服務將被添加到工作流運行時引擎中
internal class LocalService : ILocalService
{
 public event EventHandler<ExternalDataEventArgs> InvokedWorkflowComplete;
 public void WorkComplete(Guid HostWFGuid)//實現接口中聲明的方法
 {
  if (InvokedWorkflowComplete != null)
  {
   InvokedWorkflowComplete(null, new ExternalDataEventArgs(HostWFGuid));
  }
 }
}

上面定義中,基本遵循了“死”格式,除了方法名稱外。在本文中先不詳細討論。

七、在宿主中操作工作流實例與本地服務

根據前面的要求,本地服務負責工作流實例與宿主間的通信中介,而加載本地服務的工作是在宿主中完成的。下面給出了宿主部分(program.cs)完整的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;

using System.Workflow.ActivitIEs;//ExternalDataExehangeService
namespace InvokeWorkflowActivityDemo
{
 class Program
 {
  static Guid HostWFGuid;//用於記憶父工作流實例的ID標記
  static LocalService ls;
  static void Main(string[] args)
  {
   using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
   {
    //下面這幾行是必需的死套路
    //加載本地服務
    ExternalDataExchangeService dataService = new ExternalDataExchangeService();
    workflowRuntime.AddService(dataService);
               
    //將自定義的本地通信服務加載到本地服務中
    ls = new LocalService();
    dataService.AddService(ls);

    //事件初始狀態為終止狀態(此時任何線程可以使用此事件)
    AutoResetEvent waitHandle = new AutoResetEvent(false);
    workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
    {
     //如果將要產生僅一個子工作流,那麼需要檢查工作流是否完成,而不是主工作流。
     if (e.WorkflowInstance.InstanceId != HostWFGuid)
     {
      //通過本地服務的特定方法通知主工作流,調用工作流完成
      ls.WorkComplete(HostWFGuid);
     }
     else
     {
      //此時是主工作流自身,將事件的狀態位置設置為終止狀態,允許一個或多個等待線程繼續。
      waitHandle.Set();
     }
    };
    workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
    {
     Console.WriteLine(e.Exception.Message);
     waitHandle.Set();
    };
    //啟動父工作流實例
    WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(Workflow1));
    HostWFGuid = instance.InstanceId;//記下父工作流實例的ID標記
    instance.Start();
    waitHandle.WaitOne();//阻止當前線程,直到當前waitHandle收到信號。
    Console.ReadLine();
   }
  }
 }
}

根據MSDN聲明,啟動工作流的實例之前,必須將 ExternalDataExchangeService 添加到工作流運行時引擎,然後將自定義通信服務添加到 ExternalDataExchangeService。詳情請參考MSDN文章《在工作流中使用本地服務》。

八、運行實例

按F5運行控制台程序,一般順利的話,將得到如下圖所示運行時快照。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved