[WF 4 (4)] フローチャート (FlowCharts) ・・・ ”思ったままに表現する”


環境 : Visual Studio 2010 Beta 2 (.NET Framework 4)

WF 4

  1. そのアイデアとベースクラスの変更
  2. コードいらずのワークフロー (入門)
  3. ワークフローのコードと XAML の内部
  4. フローチャート (FlowCharts)
  5. アクティビティ (基礎)
  6. アクティビティコンテキスト (context) と変数 (Variable) の意義
  7. アクティビティにおけるさまざまな実行管理
  8. アクティビティのデリゲート
  9. アクティビティの非同期実行
  10. アクティビティデザイナー
  11. ブックマーク
  12. Workflow Extensions と 永続化、トラッキング
  13. デザイナーリホスティングとカスタムアプリケーション

こんにちは。

今回は、WF 4 で追加されたフローチャートのワークフローについて説明します。

フローチャート型ワークフローの意義

第 2 回で作成したサンプルでは、Sequence アクティビティを使って処理を構築しました。この方法では、例えば、While のループをおこなうには、Suquence アクティビティの子アクティビティ (Children Activities) として While アクティビティを挿入し、While の中の処理は、While アクティビティの子アクティビティとして必要なアクティビティを挿入します。While の中でいくつかの処理を流したい場合には、While アクティビティに Sequence アクティビティを挿入し、この Sequence アクティビティの中に、処理(アクティビティ)を子アクティビティとして複数個挿入します。

といった具合に、While でも、If でも、さらに While の中にまた While が入っているようなケースでも、さまざまな処理の構築をおこなうことが可能であり、これは従来の WF から踏襲した構築概念です。

しかし、下図のような処理を考えてみてください。

こうした処理は、日本ではごくごく一般的にある「差し戻し」の処理であり、上から順番に流れてくる「逐次実行型」 (シーケンシャル) のタイプのワークフローですが、実は上述した「子アクティビティ」の組み合わせによる Sequential のモデルでは構築できません。
その理由は、While の各ブロックが下図のようにネスト関係になっておらず重なってしまっているためです。

こうした場合、従来では、シーケンシャル型ではなくステートマシン型と呼ばれるワークフローを構築し、すべてをイベントドリブンに構築する必要がありました。しかし、上図をみて明らかなように、ごく一部を戻したいだけであって、本来はシーケンシャルな性質のワークフローに他なりません。ひとたびステートマシン型を使うと、引き続くすべての逐次実行な処理も、すべてイベントドリブンに組み合わせていくことになります。「本来はイベントドリブンなフローではないのに、実装上の理由でイベントドリブンを使わざるを得ない」といったケースに悩まされていた方も多かったことでしょう。(私も、何度か、開発者の方からそうした相談を受けたことがあります。。。)

フローチャートはこうした問題に対処し、まさしく「思ったままを表現する」ためのワークフローモデルとして WF 4 に新しく追加された仕組みです。

WF 4 におけるフローチャートの使用とその構造

フローチャートの作成は実に簡単です。

ワークフローのプロジェクトを新規作成してツールボックスを見ると、下図のようにフローチャート用のツールアイテムがいくつか存在します。 第 2 回では、いきなり Sequence アクティビティを挿入しましたが、フローチャートを作成するには、下図の Flowchart アクティビティを挿入し、その中で子アクティビティを挿入してフローを作成していくだけです。

アクティビティどうしをつなぐには、挿入されたアクティビティ (ノード) の端にマウスを持っていくと表示される端点をドラッグアンドドロップします。これにより、ノード間はライン (線) で結ばれます。(ラインは勿論、方向を持っており、フローチャートは有向グラフになります。)

フローは、下に順番に流していく必要はなく、どこにでも飛ばすことができます。(無論、戻すこともできます。) また、Flowchart 自身も子アクティビティを持てるただのアクティビティにすぎないので、その中に Sequence アクティビティを挿入して組み合わせたり、Pick アクティビティを挿入して待機をおこなうイベントドリブンなフローを作成することも、それらを組み合わせることもできます。

例えば、今、以下のような極めて単純なフローチャートを作成したと仮定しましょう。

この際、作成される XAML は下記の通りになります。

<Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication9.Workflow1" . . . >
  <Flowchart 
    sad:XamlDebuggerXmlReader.FileName="C:\Demo\WorkflowConsoleApplication9\WorkflowConsoleApplication9\Workflow1.xaml"
    sap:VirtualizedContainerService.HintSize="614,636">
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">False</x:Boolean>
        <av:Point x:Key="ShapeLocation">270,2.5</av:Point>
        <av:Size x:Key="ShapeSize">60,75</av:Size>
        <av:PointCollection x:Key="ConnectorLocation">300,77.5 300,107.5 300,138</av:PointCollection>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <Flowchart.StartNode>
      <x:Reference>__ReferenceID0</x:Reference>
    </Flowchart.StartNode>
    <FlowStep x:Name="__ReferenceID0">
      <sap:WorkflowViewStateService.ViewState>
        <scg3:Dictionary x:TypeArguments="x:String, x:Object">
          <av:Point x:Key="ShapeLocation">193.5,138</av:Point>
          <av:Size x:Key="ShapeSize">213,64</av:Size>
        </scg3:Dictionary>
      </sap:WorkflowViewStateService.ViewState>
      <WriteLine
        sap:VirtualizedContainerService.HintSize="213,64"
        Text="This is test" />
    </FlowStep>
  </Flowchart>
</Activity>

このように、フローチャートでは、FlowStep という見えないオブジェクト (これは、アクティビティではありません) を使って、そのラインの始点と終点を管理します。

フローチャートでは、FlowDecision、FlowSwitch (上図のツールボックス一覧を参照) というオブジェクト (これらも、実はアクティビティではありません) を使用して、条件に応じた分岐を作成し、条件に応じ自由に戻すことができます。

例えば、以下のフローを作成したと仮定します。(なお、ここにある ReadLine アクティビティはカスタムで作成したアクティビティであり、標準では含まれていません。カスタムアクティビティの作成方法については、また別途ご説明しましょう。。。)

ここでは、上図の ReadLine アクティビティで入力した内容が LastInputValue という int 型の変数 (Variable) に設定されるように構築されていると仮定しましょう。ここで、上図の FlowDecision の Condition プロパティを表示して下図の通り LastInputValue < 0 の VB 式を設定すると、このフローチャートは 0 以上の値を入力している間、ずっとループを続け、負数を入れると End ! と出力されて終了することになります。

また、下図のように、今度は FlowSwitch を使ってフローを作成したと仮定しましょう。

FlowSwitch の Expression プロパティに LastInputValue.ToString() と設定すると、1,2,3 以外が入力されるまでループを続け、1, 2, 3 のいずれかが入力されたら該当するメッセージを表示して終了します。

Comments (0)

Skip to main content