次の方法で共有


実行時間の長いワークフロー サービスを作成する

この記事では、長時間実行できる実行時間の長いワークフロー サービスを作成する方法について説明します。 ワークフローでは、追加情報を待つ間アイドル状態になることがあります。 アイドル状態になると、ワークフローは SQL データベースに永続化され、メモリから削除されます。 追加情報が使用可能になると、ワークフロー インスタンスがメモリに読み込み直されて、実行を継続します。

このシナリオでは、非常に簡略化された注文システムを実装します。 クライアントは、最初のメッセージをワークフロー サービスに送信して注文を開始します。 ワークフロー サービスは、注文 ID をクライアントに返します。 この時点で、ワークフロー サービスは、クライアントからの別のメッセージを待機しており、アイドル状態に入って、SQL Server データベースに永続化されます。 クライアントが次のメッセージを送信して項目を注文すると、ワークフロー サービスはメモリに読み込み直されて、注文の処理を終了します。

次のコード例では、項目が注文に追加されたことを示す文字列を返します。 このコード例は、テクノロジの実際の適用を意図するものではなく、実行時間の長いワークフロー サービスを示す簡単な例です。

前提条件

このチュートリアルを使用するには、次のソフトウェアがインストールされている必要があります。

  1. Microsoft SQL Server 2008
  2. Visual Studio 2012
  3. Microsoft .NET Framework 4.6.1

また、WCF と Visual Studio 2012 に精通し、プロジェクト/ソリューションの作成方法を理解している必要があります。

SQL データベースを設定する

  1. ワークフロー サービス インスタンスが永続化されるようにするには、Microsoft SQL Server をインストールして、永続化ワークフロー インスタンスを保存するようにデータベースを設定する必要があります。 [スタート] ボタンをクリックし、 [すべてのプログラム][Microsoft SQL Server 2008][Microsoft SQL Management Studio] の順にクリックして Microsoft SQL Management Studio を実行します。

  2. [接続] ボタンをクリックして SQL Server インスタンスにログオンします。

  3. ツリー ビューで [データベース] を右クリックして [新しいデータベース] の順に選択し、SQLPersistenceStore という名前の新しいデータベースを作成します。

  4. SQLPersistenceStore データベースの C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en ディレクトリにある SqlWorkflowInstanceStoreSchema.sql スクリプト ファイルを実行して、必要なデータベース スキーマを設定します。

  5. SQLPersistenceStore データベースの C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en ディレクトリにある SqlWorkflowInstanceStoreLogic.sql スクリプト ファイルを実行して、必要なデータベース ロジックを設定します。

Web ホスト ワークフロー サービスを作成する

  1. 空の Visual Studio 2012 ソリューションを作成し、OrderProcessing という名前を付けます。

  2. OrderService という新しい WCF ワークフロー サービス アプリケーション プロジェクトをソリューションに追加します。

  3. プロジェクトのプロパティのダイアログで [Web] タブをクリックします。

    1. [開始動作][ページを指定する] をクリックし、Service1.xamlx を指定します。

      ワークフロー サービス プロジェクト Web プロパティ

    2. [サーバー][ローカル IIS Web サーバーを使用する] を選択します。

      ローカル Web サーバーの設定

      警告

      この設定を行うには、Visual Studio 2012 を管理者モードで実行する必要があります。

      次の 2 つの手順で、ワークフロー サービス プロジェクトが IIS でホストされるように設定します。

  4. Service1.xamlx が開いていない場合は開き、既存の ReceiveRequest アクティビティと SendResponse アクティビティを削除します。

  5. [シーケンシャル サービス] アクティビティを選択し、 [変数] リンクをクリックします。そして、次の図に示されている変数を追加します。 こうするといくつかの変数が追加され、後でワークフロー サービスで使用されます。

    Note

    CorrelationHandle が [変数の型] ボックスにない場合は、ボックスから [型の参照] を選択します。 [型名] ボックスに「CorrelationHandle」と入力し、リスト ボックスから [CorrelationHandle] を選択して [OK] をクリックします。

    変数の追加

  6. ReceiveAndSendReply アクティビティ テンプレートをドラッグし、 [シーケンシャル サービス] アクティビティにドロップします。 このアクティビティのセットは、クライアントからメッセージを受信して、返信を送信します。

    1. Receive アクティビティを選択し、次の図で強調表示されているプロパティを設定します。

      Receive アクティビティのプロパティの設定

      DisplayName プロパティは、デザイナーに表示される Receive アクティビティの名前を設定します。 ServiceContractName プロパティと OperationName プロパティは、Receive アクティビティで実装されるサービス コントラクトおよび操作の名前を指定します。 ワークフロー サービスでのコントラクトの使用方法の詳細については、「ワークフロー内でのコントラクトの使用」を参照してください。

    2. ReceiveStartOrder アクティビティの [定義] リンクをクリックし、次の図に示されているプロパティを設定します。 [パラメーター] オプション ボタンが選択され、p_customerName という名前のパラメーターが customerName 変数にバインドされていることに注目してください。 これにより、Receive アクティビティがいくつかのデータを受け取り、そのデータをローカル変数にバインドするように設定されます。

      Receive アクティビティで受信したデータの設定

    3. SendReplyToReceive アクティビティを選択し、次の図で強調表示されているプロパティを設定します。

      SendReply アクティビティのプロパティの設定

    4. SendReplyToStartOrder アクティビティの [定義] リンクをクリックし、次の図に示されているプロパティを設定します。 [パラメーター] オプション ボタンが選択され、p_orderId という名前のパラメーターが orderId 変数にバインドされていることに注目してください。 この設定により、SendReplyToStartOrder アクティビティが型文字列の値を呼び出し元に返すように指定されます。

      SendReply アクティビティのコンテンツ データの構成

    5. Assign アクティビティをドラッグし、Receive アクティビティと SendReply アクティビティの間にドロップします。次の図に示されているようにプロパティを設定します。

      assign アクティビティの追加

      これにより、新しい注文 ID が作成され、orderId 変数に値が配置されます。

    6. ReplyToStartOrder アクティビティを選択します。 プロパティ ウィンドウで、CorrelationInitializers の省略記号ボタンをクリックします。 [初期化子の追加] リンクを選択し、[初期化子] テキスト ボックスに「orderIdHandle」と入力します。[関連付けの種類] として [クエリ関連付け初期化子] を選択し、[XPATH クエリ] ドロップダウン ボックスの p_orderId を選択します。 これらの設定を次の図に示します。 [OK] をクリックします。 これにより、クライアントとワークフロー サービスのこのインスタンス間の相関関係が初期化されます。 この注文 ID を含むメッセージが受信されると、ワークフロー サービスのこのインスタンスにルーティングされます。

      関連付け初期化子の追加

  7. 別の ReceiveAndSendReply アクティビティをドラッグし、ワークフローの最後 (最初の Receive アクティビティと SendReply アクティビティを含む [シーケンス] の外側) にドロップします。 これで、クライアントで送信された 2 つ目のメッセージを受信し、それに応答します。

    1. 新しく追加された Receive アクティビティと SendReply アクティビティを含む [シーケンス] を選択し、 [変数] ボタンをクリックします。 次の図で強調表示されている変数を追加します。

      新しい変数の追加

      また、Sequence スコープ内の [文字列] として orderResult を追加します。

    2. Receive アクティビティを選択し、次の図に示されているプロパティを設定します。

      Receive アクティビティのプロパティの設定

      注意

      必ず、ServiceContractName フィールドを ../IAddItem で変更してください。

    3. ReceiveAddItem アクティビティの [定義] リンクをクリックし、次の図に示されているパラメーターを追加します。これにより、Receive アクティビティが、2 つのパラメーター、注文 ID、および注文されている項目の ID を受け取るように設定されます。

      2 番目の receive のパラメーターの指定

    4. CorrelateOn の省略記号ボタンをクリックし、「orderIdHandle」を入力します。 [XPath クエリ] でドロップダウン矢印をクリックし、p_orderId を選択します。 これにより、2 つ目の Receive アクティビティに相関関係が設定されます。 関連付けの詳細については、「関連付け」を参照してください。

      CorrelatesOn プロパティの設定

    5. If アクティビティをドラッグし、ReceiveAddItem アクティビティの直後にドロップします。 このアクティビティは、if ステートメントと同様に動作します。

      1. Condition プロパティを itemId=="Zune HD" (itemId="Zune HD" for Visual Basic) に設定します。

      2. Assign アクティビティを 1 つずつ、Then セクションと Else セクションにドラッグ アンド ドロップし、次の図に示されているように Assign アクティビティのプロパティを設定します。

        サービス呼び出しの結果の割り当て

        条件が true である場合は、Then セクションが実行されます。 条件が false である場合は、Else セクションが実行されます。

      3. SendReplyToReceive アクティビティを選択し、次の図で強調表示されている DisplayName プロパティを設定します。

        SendReply アクティビティ プロパティの設定

      4. SetReplyToAddItem アクティビティの [定義] リンクをクリックし、次の図に示されているように設定します。 これにより、SendReplyToAddItem アクティビティが orderResult 変数に値を返すように設定されます。

        SendReply アクティビティのデータ バインディングの設定

  8. web.config ファイルを開いて、次の要素を <behavior> セクションに追加し、ワークフロー永続化を有効にします。 (接続文字列を忘れずに完了してください)。

    <sqlWorkflowInstanceStore connectionString="...;Asynchronous Processing=True" instanceEncodingOption="None" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="BasicRetry" hostLockRenewalPeriod="00:00:30" runnableInstancesDetectionPeriod="00:00:02" />
              <workflowIdle timeToUnload="0"/>
    
  9. ソリューションをビルドします。

クライアント アプリケーションを作成してワークフロー サービスを呼び出す

  1. OrderClient という新しいコンソール アプリケーション プロジェクトをソリューションに追加します。

  2. 次のアセンブリへの参照を OrderClient プロジェクトに追加します。

    1. System.ServiceModel.dll

    2. System.ServiceModel.Activities.dll

  3. サービス参照をワークフロー サービスに追加し、OrderService を名前空間として指定します。

  4. クライアント プロジェクトの Main() メソッド内に次のコードを追加します。

    static void Main(string[] args)
    {
       // Send initial message to start the workflow service
       Console.WriteLine("Sending start message");
       StartOrderClient startProxy = new StartOrderClient();
       string orderId = startProxy.StartOrder("Kim Abercrombie");
    
       // The workflow service is now waiting for the second message to be sent
       Console.WriteLine("Workflow service is idle...");
       Console.WriteLine("Press [ENTER] to send an add item message to reactivate the workflow service...");
       Console.ReadLine();
    
       // Send the second message
       Console.WriteLine("Sending add item message");
       AddItemClient addProxy = new AddItemClient();
       AddItem item = new AddItem();
       item.p_itemId = "Zune HD";
       item.p_orderId = orderId;
    
       string orderResult = addProxy.AddItem(item);
       Console.WriteLine("Service returned: " + orderResult);
    }
    
  5. ソリューションをビルドし、OrderClient アプリケーションを実行します。 クライアントに次のテキストが表示されます。

    Sending start messageWorkflow service is idle...Press [ENTER] to send an add item message to reactivate the workflow service...
    
  6. ワークフロー サービスが永続化されていることを確認するには、 [スタート] メニューで [すべてのプログラム][Microsoft SQL Server 2008][SQL Server Management Studio] の順にクリックして SQL Server Management Studio を起動します。

    1. 左側のペインで [データベース][SQLPersistenceStore][ビュー] の順に展開します。System.Activities.DurableInstancing.Instances を右クリックし、 [上位 1000 行を選択] をクリックします。 [結果] ペインで、少なくとも 1 つのインスタンスが一覧に含まれていることを確認します。 実行中に例外が発生した場合は、前の実行のその他のインスタンスがある可能性があります。 既存の行を削除するには、System.Activities.DurableInstancing.Instances を右クリックし、 [上位 200 行を編集] をクリックし、 [実行] ボタンをクリックしたら、結果のペインのすべての行を選択し、 [削除] をクリックします。 データベースに表示されているインスタンスが、アプリケーションで作成されたインスタンスであることを確認するには、クライアントを実行する前に、Instances ビューが空であることを確認します。 クライアントが実行されると、クエリ ([上位 1000 行を選択]) を再実行し、新しいインスタンスが追加されていることを確認します。
  7. Enter キーを押して、項目の追加メッセージをワークフロー サービスに送信します。 クライアントに次のテキストが表示されます。

    Sending add item messageService returned: Item added to orderPress any key to continue . . .
    

関連項目