この記事は機械翻訳されたものです。
基礎
Windows の [ワークフローのデザイン パターン
Matthew Milner
MSDN コード ギャラリー からのコード ダウンロード
オンラインのコードを参照します。
内容
データの N 個のアイテムの作業を行う
タイムアウトを聴く
ステート マシンのバリエーション。
収集を散布図します。
複数の操作でワークフロー サービスを開始
デザイン パターンは、ソフトウェア開発タスクを解決するには、共通の反復可能なアプローチを提供し、多くの異なるパターンはコードの特定の目的は、実行する方法を説明できます。 開発者作業を開始、Windows ワークフロー Foundation (WF) 方法について質問が多くの場合、テクノロジの一般的なタスクを実行します。 今月 WF で使用されるいくつかのデザイン パターンをについて説明します。
データの N 個のアイテムの作業を行う
多くの場合、ワークフローがいないドリブン純粋なロジックが、組織内のユーザーの一覧や、注文の一覧などのデータによっても一連の手順で、ワークフローの各項目に対して 1 回実行する必要があります。 おそらくいないパターン自体で、この単純で再利用可能なビットのロジックは、重要なコンポーネント、この資料で説明する他のパターンのです。 キーこのシナリオはデータのコレクションを反復し、コレクション内の各項目に対して同じ操作の実行を複製処理プログラム アクティビティを使用してください。
レプリケーター アクティビティには、イテレーション、データ項目、および実行の中断をできるようにする条件ごとに、子アクティビティの初期化のイベントをドライブにデータ項目のコレクションのプロパティがあります。 基本的に、複製処理プログラム活動習得 DoWhile スタイルの条件付き実行を組み合わせて ForEach セマンティクスします。
たとえば <string> の一覧の種類のプロパティを持つ従業員の電子メール アドレスを含むワークフローを指定することができます、リストを反復し、ように、各従業員に送信します。 図 1 .
図 1 の 複製処理プログラム withSendMail の利用状況
このシナリオでは、複製処理プログラム活動いる必要 IEnumerable インターフェイスに表示される電子メール アドレスを含むを実装するコレクションに関連付けられている InitialChildData プロパティあります。 これらのアドレスの各イテレーションの受信者のアドレスを設定する使用されます。 ChildInitialized イベントを処理してにアクセスするデータ項目と実行される動的アクティビティ インスタンス。 図 2 はコレクションから電子メール アドレスをイベントに渡され、関連する電子メール アクティビティ インスタンスでは、RecipientAddress プロパティを設定する方法を示しています。
図 2 の子アクティビティの初期化中
public List<string> emails = new List<string>
{"matt@contoso.com","msdnmag@example.com"};
private void InitChildSendMail(object sender, ReplicatorChildEventArgs e)
{
SendMailActivity sendMail = e.Activity as SendMailActivity;
sendMail.RecipientAddress = e.InstanceData.ToString();
}
レプリケーター アクティビティは順番にまたは並列で実行できます。 連続モードでは複製処理プログラムが各イテレーションを新規のイテレーションを開始する前に完了を待ちます。 並列モードですべてのアクティビティが初期化され、同じ時刻にスケジュールあり、実行並列活動に同様を除く各分岐に、同じ定義と。 データ項目を反復処理、並列でいくつかの操作を起動および各項目に対する応答を待機することは、この記事で説明したいくつかなど、多くのデザイン パターンで重要です。
タイムアウトを聴く
タイムアウトのシナリオと応答で何らかの入力は一定の時間に対してのみを待機する必要があります。 たとえば、する場合がありますが通知、マネージャー、電子メール メッセージと、マネージャー場合は、応答を待機する必要が応答しない、時間の特定の期間内、ワークフロー、アラームの送信などのそれ以上のアクションを考慮します。
このパターンの実装の中心は、受信アクティビティです。 一時停止し、同時に多数の異なるイベントや入力を待機するワークフローを受信アクティビティにできます。 この機能は、並列活動にも実現できますが差 Parallel アクティビティは、すべてのイベントを待機するのに対し、リッスン活動を最初のイベントが発生し、すべて他のイベントを待機して停止反応ことです。 この機能の遅延活動に用意されている指定した時間待機する機能を組み合わせる待機するイベントがタイムアウト イベントが発生しない場合、ワークフローでできます。 図 3 の Windows 通信基盤 (WCF) 経由で到着するメッセージまたは期限が切れるようにタイムアウトは、待機しています、リッスン アクティビティを示します。 受信アクティビティを複数分岐を指定できることができますしたがっては待機多くの異なるイベントと同時を確認します。
図 3 複数の分岐での利用状況を聴く
このような実装は、一定時間応答を待機するワークフローできます。 通常は、タイムアウトが発生した場合、ワークフローはためのものの適切な処置を実行します。 タイムアウトが発生したら、管理者の承認の例の展開、彼女が、未処理の要求を承認する必要マネージャーを知らせてある必要があります。 アラームを表示、マネージャーは後、ワークフローは、応答と、タイムアウトの待機の状態に復元する必要があります。 リッスンを囲む特定の条件が満たされるまでの待機を続行するワークフローを有効にアクティビティを繰り返し使用します。 受信アクティビティの分岐、内部の条件が操作適切に待機を続行するとき、または必要とされている応答の受信後に移動します。 単純な場合は、フラグを使用する、繰り返しの原因は、条件を管理アクティビティにフラグが設定されてまでループします。 したがって、マネージャーが応答を送信、フラグ設定できると、繰り返しワークフローを次のアクティビティに移動できるように、アクティビティを閉じます。 遅延活動に、分岐、遅延の後、アクティビティはマネージャーに通知を送信を使用条件が繰り返しを強制的に設定されてもいるためアクティビティを 図 4 に示すように、もう一度、子アクティビティをスケジュールします。
図 4 で確認メッセージの送信を実行中に受信待ち
この例では、待機を停止するトリガーの条件は、マネージャーからの応答だけですが、もちろん、受信した入力データに対して複雑な評価の任意のレベルを実行できます。 方法 1 つは、ルール セット、および Policy アクティビティを使用してワークフローは、次の手順に移動するすべての条件を満たしているかどうかを決定することです。
ステート マシンのバリエーション。
順次ワークフローの代わりに、ステート マシン ワークフローを開発する、リッスン タイムアウト パターンを持つ 1 つのバリエーションの起こります。 ここでは、State アクティビティ リッスン活動の行わしてなど遅延アクティビティを使用して、同時に複数のイベントを待機する機能を提供します。 指定した状態で、承認を待機中、モデルできます応答またはタイムアウトは、待機をする前に、のとして同じシナリオ。 図 5 は前に、のとして同じロジックを実装するが、ステート マシン ワークフローを使用して、サンプル ワークフローを示しています。
図 5 の ステート マシンのリスニング
方が実際には、While の必要性がないため、ここで、条件を管理する簡単です活動。 代わりに、遅延が発生にリマインダーを送信または他のアクション実行できし移行現在の状態に戻す SetState 活動にすると、もう一度実行するには、遅延アクティビティを使用して、タイムアウトをリセットできます。 応答が受信を続けるための条件する場合、SetState 活動は、次の状態に移動する使用します。 図 6 の両方の分岐を示しています。
図 6 状態の利用状況でのリッスン
収集を散布図します。
いくつかの作業に多くの子ワークフローを開始する必要が、いる場合は、収集散布パターンを使用します。 これらのワークフローがすべては作業、同じさまざまなデータは、または各別の作業を実行する可能性があります。 目標は、すべての作業を開始、タスクを実行、高速化可能であれば、複数のスレッドの使用を最適化および各タスクが完了して結果を収集するには、親のワークフローに通知します。
複数のワークフローは、レプリケーター アクティビティと InvokeWorkflow 活動をによるにだけ起動できます。 ワークフローがする目的が、非同期的に開始されてが待機している親ワークフローにより難しい子ワークフローからのデータを受信できるブロックの活動を必要な。 受信アクティビティを使用して、親ワークフローを待つ各子アクティビティ終了してから各ワークフローが開始されましたが、結果を受信します。 図 7 の親のワークフローでこのパターンの概要を示します。
図 7 InvokeWorkfl と複製処理プログラム ow とが表示される作業
このパターンの実装、こと子のワークフローが正しくコールバック WCF を使用して、親のワークフローに確認する手順が必要ないくつかのキーに単純な外観を図になります。 コンテキスト情報を各子、子、ワークフロー インスタンス識別子と、正しい Receive アクティビティを選択するには、会話識別子を含む、親ワークフローにデータを送信を有効にする、親ワークフローから渡される必要が。 あります また、WCF サービスの通信を有効にすると、親のワークフローをホストする必要がありますは開始 WorkflowRuntime を使用して 図 8 に示すように 。
図 8 の WCF サービスとしてワークフローがホストされている必要があるを開始
WorkflowServiceHost host = new WorkflowServiceHost(typeof(MSDN.Workflows.
ParentWorkflow));
try
{
host.Open();
WorkflowRuntime runtime = host.Description.Behaviors.
Find<WorkflowRuntimeBehavior>().WorkflowRuntime;
WorkflowInstance instance = runtime.CreateWorkflow(
typeof(MSDN.Workflows.ParentWorkflow));
instance.Start();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadLine();
}
finally
{
if (host != null && host.State == CommunicationState.Opened)
host.Close();
else
host.Abort();
}
各子ワークフローが少なくとものパラメーターを入力がならない、親のワークフロー ID と子のワークフローで処理するが必要なビジネス データのほかに、受信アクティビティの ID。 ワークフローにパラメーターは、ワークフロー定義にパブリック プロパティとして定義されます。
InvokeWorkflow 活動するおよび子ワークフローにパラメーターを渡すことができます [プロパティ] ダイアログ ボックスで、これらのプロパティを表面します。 InvokeWorkflow 活動に、パラメーターや、ワークフロー内のフィールド プロパティにバインドできます。 ただし、呼び出しのたびに一意の値が必要だために、コードで設定されるパラメーターある必要はレプリケーター アクティビティ多数のワークフローを起動するを使用する場合、各イテレーションでは、プロパティまたはフィールドで設定できます、現在の入力します。 したがって、InvokeWorkflow 活動に、パラメーター、ワークフロー内のフィールドにバインドして、子のワークフローが作成前に、コード内でこれらのフィールドが更新されます。
初期の傾きは、プロパティ設定 ChildInitialized イベント中に、複製処理プログラム、SendMail 例の以前のバージョンでは、表示すると、これは適切な開始する場所があります。 ただし、並列モードでの複製処理プログラム アクティビティを実行と、実行には、すべてのインスタンスを開始前にすべての子が初期化されます。 したがって、プロパティ ChildInitialized イベントに、設定、InvokeWorkflow のアクティビティを実行するまでと活動のすべてのインスタンスは 1 組のデータの使用。 ただし、ChildInitialized イベントはアクティビティ インスタンスおよびイテレーションを推進するデータ項目へのアクセスを提供します。 1 つの方法はデータ項目の収集を実行中に、適切なアクティビティ インスタンスに関連付けるできますように一意の識別子を持つ格納です。 インスタンス データが、辞書、ActivityExecutionContext の一意の識別子をキーに格納されるレプリケーター アクティビティの ChildInitialized イベント ハンドラーを 図 9 に示します。
図 9 のイテレーションの中にデータを保存します。
private void InitChild(object sender, ReplicatorChildEventArgs e)
{
InvokeWorkflowActivity startWF =
(InvokeWorkflowActivity)e.Activity.GetActivityByName("StartChild
Workflow");
InputValueCollection[(Guid)e.Activity.GetValue(
Activity.ActivityContextGuidProperty)] = e.InstanceData.ToString();
}
次に、InvokeWorkflow 活動を初期化すると、Invoking イベントを使用パラメーターを設定します。 この時点で実行すると、子ワークフローへの入力に必要なすべての値は利用できます。 WorkflowEnvironment からワークフロー識別子を取得することができますあり、Receive アクティビティ インスタンスのコンテキスト プロパティから会話 ID を取得できます。 最後に、ビジネス データ取得できる現在の実行コンテキストを識別子を使用しています。 図 10 は、ワークフローに渡されるパラメーターを初期化するコード、示しています。
図 10 の InvokeWorkflow の利用状況の初期化中
private void PrepChildParams(object sender, EventArgs e)
{
InvokeWorkflowActivity startWf = sender as InvokeWorkflowActivity;
ReceiveActivity receive =
(ReceiveActivity)startWf.Parent.GetActivityByName(
"ReceiveChildCompletion");
Contracts.ChildWFRequest request = new Contracts.ChildWFRequest();
request.WFInstanceID = WorkflowEnvironment.WorkflowInstanceId.ToString();
request.ConversationID = receive.Context["conversationId"];
request.RequestValue =
InputValueCollection[(Guid)startWf.Parent.GetValue(
Activity.ActivityContextGuidProperty)];
StartWF_Input = request;
}
子ワークフローが開始すると後に、作業が終了し、処理が完了すると、[使用して、親のワークフローの通知を送信アクティビティを実行する開始できます。 メッセージを送信、する前には、コンテキストをメッセージを取得、親のワークフローで正しい受信アクティビティに送信されたことを確認する、送信アクティビティで設定する必要があります。 親から渡された値を使って、コンテキスト正しく設定できます、BeforeSend イベントを使用して次に示すように。
e.SendActivity.Context = new Dictionary<string, string>{
{"instanceId", InputValues.WFInstanceID},
{"conversationId", InputValues.ConversationID}};
すべてこれらの部分の場所や、親のワークフローが開始活動データのコレクションを反復する複製処理プログラムの場合と各アイテムの 1 つの子のワークフローを開始し、それぞれを並列にからのメッセージを待機します。 子のワークフローが完了として、メッセージを送信後、その結果戻る報告されているすべての子のワークフロー処理を続行できる親に戻る。 このアプローチを使用して、子のワークフローがそれぞれ、本当に非同期処理を提供する独自のスレッドが、同じ時刻に実行できます。
複数の操作でワークフロー サービスを開始
多くのサンプルではワークフロー サービスが 1 回の操作をモデリングする 1 つの受信活動を始めます。 ここで説明したシナリオでは、1 つ以上のメソッド呼び出しで、ワークフロー サービスを開始する必要があります。 つまり、クライアント アプリケーションが、ワークフローとの対話を開始する同じ操作を常に呼び出されませんされ、複数の操作の基に起動できるように、ワークフローを設計することができる必要があります。
実際には後の最初の要求に要求を処理する方法に応じて、このパターンの 2 つの異なる変形があります。 最初のオプションをいくつかの操作のいずれかで開始し、その操作が完了したら、操作を呼び出すできます別のポイントを定義するまで、ワークフロー処理にワークフローを有効にです。 この目標を達成するには、受信アクティビティに戻って、ワークフロー定義の中の最初の活動として使用をします。 次に、[活動の各ツリー受信アクティビティを追加し、適切なサービスの操作に関する情報で構成を 図 11 に示すように、処理の必要なパラメーターをバインドします。
図 11 複数リッスンの利用状況での活動が表示されます。
重要な手順は、受信アクティビティでのすべての受信アクティビティが、CanCreateInstance プロパティを [True] に設定できるようにです。 これによって、WCF ランタイムことコンテキスト情報がない場合、既存のワークフロー インスタンスを示す要求で使用できる、そのは、構成処理に基づいた新しいインスタンスを起動する実行可能します。 受信以外のアクティビティをワークフローを作成する少し奇数思わは、ランタイム インスタンス、しが開始されると作成だけし、Receive アクティビティを WCF メッセージの内容を送信しようとします。 ここでは、ワークフローが開始したら両方受信アクティビティが実行してからの入力を待ってします。
このパターンの 2 つのバリエーションがあることを説明しました。 使用すると、受信アクティビティ前の例で行いましたが、ワークフローを開始、操作のいずれか、後、受信アクティビティの完了し 1 つの分岐は行われ、サービスが、他の操作の要求を受信することでなくなったことは、応答でモデル化します。 これは、場合があります正確に一部のシナリオに必要ないてする他のワークフローに移動する前に操作のセット全体の処理をします。 つまり、わかっているが、ワークフロー、サービス契約でのさまざまな操作で複数の要求を受け取るがどの要求を最初になりますがよくわからない。 ここでは、リッスン活動の代わりに、Parallel アクティビティを受信アクティビティを True に設定、CanCreateInstance プロパティを含む各支社で使用できます。 ワークフローを操作を開始できますが、すべて、その他操作呼び出しの受信、さまざまな分岐でモデル化する状態、ワークフローはそのままそのもです。
最後に、ステート マシン ワークフローを使用しているときに、特定のメッセージを受け取ったときのワークフローの動作を柔軟持っています。 初期状態がいくつかイベント ドリブン活動、それぞれ開始活動として、受信アクティビティに含まれるステート マシンを考慮し、各受信マークの作成を有効にします。 通常、State アクティビティ機能リッスン活動に似た、しかも、開発者として、決定コントロールが、現在の状態から別の状態に移動するとします。 リッスン活動が完了したら、それが終了し、コントロールの順序で次のアクティビティに移動します。 State アクティビティで、ワークフローは、新しい状態に移動しない場合、分岐を実行される、ワークフローは現在の状態のままし、定義の入力を待機し続けます。
リッスン活動などのセマンティクスを使用するには、[1 つの操作が呼び出されるときに、次の状態に、ワークフローを移動すると、SetState 活動を使わなければなりません。 これは、通常で呼び出される別の WCF 操作に対して待機している状態に、ワークフローを入れます。 、その一方で、たい場合セマンティクス近く、すべての操作する必要があるれる、並列モデルですが特定の順序でない、し各 Receive アクティビティ後必要がするありますや移行 SetState アクティビティを、self-transition、同じ状態に戻さを使用して状態を変更しないのかを選択します。
この最後のオプションではありません、Parallel アクティビティ モデルのような完全可能性のある重要な 1 つの方法です。 並列、活動に、操作を呼び出した後、呼び出せませんもう一度、Parallel アクティビティの後に、任意の場所をモデル化しない限り。 状態コンピューター モデルでは、ワークフローが同じ状態では、残っている場合、操作が呼び出された後受信できるメッセージの他の操作や、元の操作をします。 実際には、状態提供できます、受信アクティビティのようなセマンティクスを繰り返しで、すべてのイベントを待機して、1 つのイベントに対応し、戻すループ、これら同じすべてのイベントを待機して再度活動。
ごにコメントや質問、 mmnet30@microsoft.com.
Matt Milner は Pluralsight、(WCF、Windows のワークフロー、BizTalk、"Dublin"、および Azure サービス プラットフォーム) に接続されているシステム テクノロジを焦点彼場所で技術スタッフのメンバーです。 Matt は、Microsoft .NET アプリケーションの設計と開発を専門とするフリー コンサルタントもあります。 Matt は定期的に自分愛テクノロジの技術などのローカル、地域、および国際のカンファレンスで話すことによって共有されます。 Ed。 マイクロソフトは、MVP 彼コミュニティ コントリビューション接続型システムのテクノロジの周囲のとして Matt を認識が。 Matt は自分のブログを使用して連絡先します。 pluralsight.com/community/blogs/matt/.