ネイティブ アクティビティを使用したカスタム複合

CustomCompositeNativeActivity サンプルでは、他の Activity オブジェクトをスケジュールしてワークフローの実行のフローを制御する NativeActivity を作成する方法を示します。 この方法を示すために、このサンプルでは一般的な制御フローである Sequence と While の 2 つを使用します。

サンプルの詳細

MySequence から始めるとき、最初に気付くことは、それが NativeActivity から派生しているということです。 NativeActivity は、Activity メソッドに渡される NativeActivityContext を介して、ワークフロー ランタイム一式を公開する Execute オブジェクトです。

MySequence は、ワークフローの作成者によって設定された Activity オブジェクトのパブリック コレクションを公開します。 ワークフローの実行前に、ワークフロー ランタイムがワークフローの各アクティビティに対して CacheMetadata メソッドを呼び出します。 このプロセスの実行中に、ランタイムによって、データのスコープや有効期間を管理するための親子のリレーションシップが確立されます。 CacheMetadata メソッドの既定の実装では、MySequence アクティビティの TypeDescriptor インスタンス クラスを使用して、Activity 型または IEnumerable<Activity> 型のパブリック プロパティを MySequence アクティビティの子として追加します。

アクティビティで子アクティビティのパブリック コレクションを公開するときは、それらの子アクティビティ間で状態を共有すると考えられます。 そのため、親アクティビティ (この場合は MySequence) で、子アクティビティがそれを実現するための変数のコレクションも公開することをお勧めします。 子アクティビティと同様に、CacheMetadata メソッドで、Variable 型または IEnumerable<Variable> 型のパブリック プロパティを MySequence アクティビティに関連付けられた変数として追加します。

MySequence の子によって操作されるパブリック変数に加えて、MySequence では、子の実行の進行状況を追跡する必要もあります。 これを実現するために、プライベート変数 currentIndex を使用します。 この変数は、MySequence アクティビティの AddImplementationVariable メソッド内に MySequence メソッドの呼び出しを追加することで、CacheMetadata 環境の一部として登録されています。 ActivityMySequence コレクションに追加された Activities オブジェクトは、この方法で追加された変数にアクセスできません。

MySequence をランタイムで実行すると、ランタイムがその Execute メソッドを呼び出し、NativeActivityContext を渡します。 NativeActivityContext は、引数と変数の逆参照と、他の Activity オブジェクトや ActivityDelegates のスケジュールを行うランタイムに返すアクティビティのプロキシです。 MySequence は、InternalExecute メソッドを使用して、最初の子と後続のすべての子を単一のメソッドでスケジュールするロジックをカプセル化します。 このメソッドは、まず currentIndex を逆参照します。 Activities コレクションに含まれる数と等しい場合、シーケンスは終了し、アクティビティが処理をスケジュールせずに戻り、ランタイムによって状態が Closed に変更されます。 currentIndex がアクティビティの数より少ない場合は、Activities コレクションから次の子が取得され、MySequenceScheduleActivity を呼び出して、スケジュールする子、および InternalExecute メソッドを指す CompletionCallback を渡します。 最後に、currentIndex がインクリメントされ、制御がランタイムに戻されます。 MySequence のインスタンスで子 Activity オブジェクトがスケジュールされていれば、ランタイムはそのインスタンスの状態が Executing であると見なします。

子アクティビティが完了すると、CompletionCallback が実行され、 ループが先頭から継続されます。 Execute と同様、CompletionCallbackNativeActivityContext を受け取り、実装側へのアクセスをランタイムに提供します。

MyWhileMySequence と異なるのは、1 つの Activity オブジェクトを繰り返しスケジュールし、Condition という名前の Activity<TResult><bool> を使用して、そのスケジュールを実行するかどうかを判断することです。 MySequence と同様に、MyWhile でも、InternalExecute メソッドを使用してスケジュール ロジックを集中化しています。 OnEvaluationCompleted という名前の CompletionCallback<TResult><bool> を使用して ConditionActivity<bool> をスケジュールします。 Condition の実行が完了すると、その結果を、この CompletionCallback を通じて、result という名前の厳密に型指定されたパラメーターで使用できるようになります。 true の場合、MyWhileScheduleActivity を呼び出し、CompletionCallback として BodyActivity オブジェクトと InternalExecute を渡します。 Body の実行が完了すると、Condition でもう一度 InternalExecute がスケジュールされ、再度ループが開始されます。 Conditionfalse を返すと、MyWhile のインスタンスが Body をスケジュールせずに制御をランタイムに戻し、ランタイムによって状態が Closed に変更されます。

サンプルをセットアップ、ビルド、および実行するには

  1. Visual Studio で Composite.sln サンプル ソリューションを開きます。

  2. ソリューションをビルドして実行します。