WFが提供するアクティビティ群
では早速、WFを使ってワークフローを実行…したいところですが、まずはWFの準備するアクティビティ群について確認しておきましょう。
Visual Studio 2005 Extensions for WFがインストールされていれば、WFで使用できるアクティビティとして、次のようなツールボックスが表示されるはずです。
代表的なアクティビティについて、概要を示します。
アクティビティ | 概要 |
CallExternalMethod | 外部のメソッドを呼び出す |
Code | コードを実行する |
CompensatableSequence | エラーが発生した場合に補正処理を実行する |
ConditionedActivityGroup | 条件を満たすまで処理を行う |
Delay | 指定時間実行を遅延させる |
EventDriven | イベント発生時に処理を行う |
IfElse | 条件に基づいてIf~Then~Else処理を行う |
InvokeWebService | Webサービスを実行する |
InvokeWorkflow | 他のワークフローを実行する |
Parallel | 複数のアクティビティを並列実行する |
SetState | ステートマシンワークフローで状態を遷移させる |
Sequence | 複数のアクティビティを連続して実行する |
State | ステートマシンワークフローの状態を定義する |
StateInitialization | 他の状態から遷移してきたときに処理を行う |
StateFinalization | 他の状態に遷移するときに処理を行う |
Suspend | ワークフローの実行を中断する |
SynchronizationScope | ワークフロー内で共有データにアクセスする部分を指定する |
Terminate | ワークフローの実行を終了する |
Throw | 例外を送出する |
TransactionScope | トランザクション対象の部分を指定する |
WebServiceInput | Webサービスとして公開されたワークフローでリクエストを受信する |
WebServiceOutput | Webサービスとして公開されたワークフローでレスポンスを送信する |
While | 条件を満たす限り処理を行う |
これらのアクティビティを組み合わせてワークフローを作成していきます。
シーケンシャル ワークフローによるサンプル
では、早速シーケンシャル ワークフローによるサンプルを作成してみましょう。
最初の一歩~Codeアクティビティ
Visual Studio 2005を起動し、新しいプロジェクトを作成します。Visual Studio 2005 Extensions for WFが正しくインストールされていれば、プロジェクトの種類として[Workflow]というカテゴリが追加されているはずです。今回は[シーケンシャル ワークフロー コンソール アプリケーション]を選択し、「WFSequenceSample」という名前でプロジェクトを作成します。
WPF/WCFのExtensionsがベータ版であることの影響でしょうか。
ファイル名 | 概要 |
Workflow1.cs | ワークフロークラスファイル。イベントハンドラやユーザー定義プロパティなどを記述する |
Workflow1.designer.cs | Visual Studioがワークフロー上に配置したコントロールの関係などを記録するためのファイル。Workflow1.csのパーシャルクラス |
Workflow1.rules | ワークフローで使用したルール条件(後述)を保存するXMLファイル |
Program.cs | ワークフローを実行するためのクラスファイル |
新しいプロジェクトを作成すると、自動的にシーケンシャルワークフローのひな型が定義されます。
開始アイコンから終了アイコンへとフローが流れていくイメージです。
では、最初にCodeアクティビティをツールボックスからワークフローにドラッグ&ドロップしてみましょう。"アクティビティをドロップしてシーケンシャル ワークフローを作成します"という部分にドロップしてください。
ドロップしたCodeアクティビティをダブルクリックすると自動的にcodeActivity1_ExecuteCode
というメソッドが作成されます。お約束通り、Hello Worldを書き込みましょう。
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("Hello WF World!"); Console.ReadKey(); }
[F5]キーを押して実行しましょう。
無事メッセージがコンソールに出力されるはずです。何かキーを押すと終了します。
ワークフローはどのように実行されているのか
あまりにあっけない結果ではありましたが、生成されたコードを確認してみましょう。
「Workflow1.cs」を見ると、コンストラクタと、先ほど作成したCodeアクティビティで実行するコードがあるだけです。ワークフローを実行するためのコードは「Program.cs」にあるようです。
static void Main(string[] args) { using(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(WFSequenceSample.Workflow1)); instance.Start(); waitHandle.WaitOne(); } }
ここでの重要な登場人物はSystem.Workflow.Runtime.WorkflowRuntime
クラスです。このクラスはワークフローを実行するためのランタイムで、1つのプロセスに付き1つだけインスタンスを生成し、その上でワークフローを実行します。
続いてワークフロー終了に関するハンドラ登録を行った後、WorkflowRuntime#createWorkflow
メソッドからSystem.Workflow.Runtime.WorkflowInstance
インスタンスを生成しています。引数にWFSequenceSample.Workflow1
クラスの型が渡されているので、ここで実行するワークフローを見分けていることが分かります。その後Start
メソッドで実行を開始します。
それぞれの代表的なメンバを記します。
メンバ | 概要 |
IsStartedプロパティ | ワークフローが実行されているかどうか |
AddServiceメソッド | SQL Serverへの永続化サービスなど、ワークフロー実行の際に使用するサービスを追加する |
CreateWorkflowメソッド | ワークフローインスタンスを生成する |
GetWorkflowメソッド | 特定のGUIDを持つワークフローインスタンスを取得する |
メンバ | 概要 |
InstanceIdプロパティ | ワークフローインスタンスに割り当てられたGUID |
Unloadメソッド | ワークフローインスタンスをメモリから削除し、永続化する |
Loadメソッド | 永続化したワークフローインスタンスを読み込む |
Suspendメソッド | ワークフローインスタンスを一時停止する |
Resumeメソッド | 一時停止したワークフローインスタンスを再開する |
なお、AutoResetEvent
クラスはSystem.Threading名前空間のクラスで、複数スレッド間での同期を取るために用いられます。ここではワークフロー実行完了を待つために使用しています。