特集

Windows Workflow Foundation概説

巷で話題のWFの可能性を探ろう!

株式会社アークウェイ 黒石 高広
2006/04/05

Page1 Page2 Page3

4. WFの基本的な動作を探る

 まずはWFのデザインの流れについて解説する。

 WFは、Visual Studio(現在は2005のみ)を利用して、ワークフローをデザインできる。デザイン画面で設計を行ったワークフローの定義は、C#やVisual Basicなどのコード・ファイルとして保存され、.NETアセンブリにコンパイルされ、CLR上で実行される。

 また、コード・ファイルだけでなく、XOML*3というワークフロー定義のXMLファイルとしてもワークフローを記述することができる(Visual Studioのデフォルト操作では、ワークフロー定義はコード・ファイルとして扱われるが、プロジェクトに新しい項目を追加する際にコード分離付きのワークフロー項目を選択することでXOMLファイルを追加することが可能である)。このXOMLファイルは、WFコンパイラによって、C#やVisual Basicなどのコード・ファイルへ変換され、最終的には上記のVisual Studioを利用した場合と同様に、.NETアセンブリにコンパイルされ実行される。

*3 マイクロソフトからの公式な発表はないが、XOMLはExtensible Object Markup Languageの略といわれている(その根拠として参考にしたサイト: Wikipedia:XOML)。

 以上のWFのデザインから実行までの流れを図4に示す。

図4 WFのデザインから実行までの流れ
デザイン画面やXOMLで記述したワークフローはC#やVisual Basicのコードに変換されるため、通常のアセンブリとして実行可能だ。

 注目すべきは、デザインされたワークフローが最終的に.NETアセンブリとして実行されることで通常の.NETアプリケーションを利用する場合と同等のパフォーマンスを得ることができ、かつXML定義としても記述できる点である。

 XML定義として記述できることで、ほかのワークフロー定義のXMLファイル*4(例えばBPELなど)をXOMLへ変換し、WFで実行することが可能となる。また現行のBizTalk Serverのオーケストレーション機能でもBPELのインポート/エクスポート機能をサポートしているので、WFでもBPELからXOMLのインポート/エクスポートをサポートしてくるものと思われる。

*4 ワークフロー定義の標準技術としては、BPELなどがある。

 では、実際にワークフローがどのように動作するか、シーケンシャル・ワークフローのサンプルとともに解説していく。

●サンプル「Hello Workflowアプリケーション」の解説

 今回の記事では、WF Beta 2(2006年3月31日時点で最新バージョンはWF Beta 2.2)を利用している。WF Beta 2のインストール手順については下記サイトを参考にしてほしい。

 また、手軽に試してみたい方はハンズ・オン・ラボが公開されているので、そちらを利用するとよいだろう。

 WFをインストールすると、Visual Studio プロジェクトにワークフロー・テンプレートが追加される。今回は、テンプレートの中から「シーケンシャル コンソール アプリケーション」を選択し、コード・アクティビティを利用して「Hello Workflow」という名前のアプリケーションを作成する。

 コード・アクティビティとは、ワークフローのインスタンス上でC#やVisual Basicなどのコードを直接実行することができるアクティビティである。

図5 シーケンシャル・ワークフロー「Hello Workflow」
ツールボックスから「コード アクティビティ」をワークフローのデザイナ(Workflow1.cs)へドラッグ&ドロップし、アクティビティ名を「HelloWorkflowActivity」に変更する。

 コード・アクティビティをダブルクリックすると、コードが実行されたときに発生するExecuteCodeイベントのイベント・ハンドラ(本稿の例ではHelloWorkflowActivity_ExecuteCodeメソッド)が作成される。

 今回は、次のコード例のように、このイベント・ハンドラに「Hello Workflow」というメッセージをコンソールに出力する内容を実装する。

private void HelloWorkflowActivity_ExecuteCode(object sender, EventArgs e)
{
  Console.WriteLine("Hello Workflow");
  Console.ReadLine();  // ユーザーに入力を要求することで実行を停止
}
コード1 コード・アクティビティのイベント・ハンドラ
Console.WriteLineメソッドを使用し、コンソールに“Hello Workflow”のメッセージを出力する。また、Console.ReadLineメソッドを使用し、コンソールをユーザー入力の待機状態にする。

 以上でワークフローは完成である。

 念のため、ここでデザイン画面で作成されたワークフロー定義が、どのようなコードとして保存されているか確認しておこう。次のコード2はその一部分だ。

public sealed partial class Workflow1
{
  private void InitializeComponent()
  {
    this.CanModifyActivities = true;

    // コード・アクティビティのインスタンス化
    this.HelloWorkflowActivity =
      new System.Workflow.Activities.CodeActivity();

    //
    // HelloWorkflowActivity
    //
    this.HelloWorkflowActivity.Name = "HelloWorkflowActivity";
    this.HelloWorkflowActivity.ExecuteCode +=
      new System.EventHandler(
        this.HelloWorkflowActivity_ExecuteCode);

    //
    // Workflow1
    //
    this.Activities.Add(this.HelloWorkflowActivity);
    this.Name = "Workflow1";
    this.CanModifyActivities = false;
  }

  private CodeActivity HelloWorkflowActivity;

  ……中略……
}
コード2 ワークフローのデザイン定義のコード・ファイル(Workflow1.cs)
デザイナ上で追加したコード・アクティビティに該当するCodeActivityクラスがインスタンス化され、ワークフローのプロパティの1つとして設定されている。またそのほかに、先ほども示したCodeActivityのExecuteCodeイベント・ハンドラの追加などを行っていることが分かる。

 このコード・ファイルを実際に実行した結果は、以下のようになる。

図6 Hello Workflowの実行結果
追加したコード・アクティビティが実行され、“Hello Workflow”のメッセージがコンソールに出力される。

 アクティビティに対してブレーク・ポイントを設定し、デバッガ・モードでステップ実行することも可能である。

 なおこれだけのコードではあまり意味がないため、Program.csファイル内に自動生成されるワークフローのインスタンス化や起動を行っているコードも紹介しておこう。

class Program
{
  static void Main(string[] args)
  {
    WorkflowRuntime workflowRuntime = new WorkflowRuntime();

    AutoResetEvent waitHandle = new AutoResetEvent(false);

    workflowRuntime.WorkflowCompleted +=
      delegate(object sender, WorkflowCompletedEventArgs e)
      {
        waitHandle.Set();
      };

    workflowRuntime.WorkflowTerminated +=
      delegate(object sender, WorkflowTerminatedEventArgs e)
      {
        Console.WriteLine(e.Exception.Message);
        waitHandle.Set();
      };

    WorkflowInstance instance =
      workflowRuntime.CreateWorkflow(
        typeof(HelloWorkflowConsoleApplication.Workflow1));

    instance.Start();

    waitHandle.WaitOne();
  }
  ……中略……
}
コード3 ワークフローを起動しているコード・ファイル(Program.cs)
作成したワークフローは、ワークフロー・ランタイム上でインスタンス化され実行される。ちなみに、このときワークフローに対してコレクションを渡すことで実行に必要な情報を渡すことも可能である。また、ワークフローとワークフローをホストするアプリケーションはイベント(イベント待機ハンドルによる同期)を通じて対話するという特徴もある。この例では、ワークフローが終了状態時、異常終了時のイベント・ハンドラの定義に.NET Framework 2.0の新機能である匿名メソッドを利用している。

 以上が、ワークフローの基本的な仕組みである。今回紹介したサンプル・コードは非常に簡単なものであるが、ワークフローの基本的な仕組みはご理解いただけたことと思う。

 それでは、次にWFの特徴の話に移りたい。引き続き、WFのアーキテクチャを解説しながら、その特徴を探っていこう。


 INDEX
  [特集] Windows Workflow Foundation概説
  巷で話題のWFの可能性を探ろう!
    1. 巷で話題のWindows Workflow Foundationって何?
  2. WFの基本的な動作を探る
    3. WFのアーキテクチャから特徴を探る
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間