次の方法で共有


タスク 2: ワークフロー サービス クライアントの作成

このタスクでは、「タスク 1: ワークフロー サービスの作成」で作成したワークフロー サービスに定義および実装した操作を呼び出す基本ワークフロー サービス クライアントを作成します。クライアントのコンソール ウィンドウには、算術演算呼び出しに渡された値と、応答として返されたサービスが表示されます。

Bb924504.note(ja-jp,VS.90).gifメモ :
このクライアントは、このチュートリアルの残りの演習で使用します。

Bb924504.note(ja-jp,VS.90).gifメモ :
Visual Studio ワークフロー デザイナを使用してワークフロー サービスを作成または管理する場合、誤った検証エラーが発生することがあります。プロジェクトを正常に作成できる場合、このような検証エラーは無視してください。

ワークフロー サービス クライアントを作成するには

  1. WorkflowServiceTutorial ソリューションを開いていない場合は、Visual Studio 2008 を開き、[ファイル] をクリックし、[開く] を強調表示し、WorkflowServiceTutorial ソリューションに移動します。

  2. WcfSvcHost.exe を実行していない場合は、Ctrl キーを押しながら F5 キーを押して WorkflowServiceTutorial サービスをビルドおよび実行します。このタスクの手順を完了するには、このサービスを実行している必要があります。[サービス] ボックスの WorkflowServiceTutorial.ServerWorkflow を右クリックし、[メタデータ アドレスをコピー] をクリックします。

  3. [ファイル] をクリックし、[追加] を強調表示して、[新しいプロジェクト] を選択します。

  4. [新しいプロジェクト] ダイアログ ボックスの [ワークフロー] で、[シーケンシャル ワークフロー コンソール アプリケーション] を選択します。

  5. プロジェクトに WorkflowServiceClient という名前を付けて [OK] をクリックします。

  6. ソリューション エクスプローラWorkflowServiceClient ノードを右クリックし、[サービス参照の追加] を選択します。

    前の手順でコピーしたメタデータ アドレスを [サービス参照の追加] ダイアログの [アドレス] ボックスに貼り付けて、[移動] をクリックします。ServerWorkflow[サービス] ボックスに表示されたら、[OK] をクリックしてサービス参照を追加します。

  7. ワークフローのワークフロー デザイナ ページを開き、[ツールボックス] ペインを使用して SendActivity アクティビティをワークフローに追加します。

  8. ワークフロー デザイナで SendActivity アクティビティを強調表示します。

  9. [プロパティ] ペインの ServiceOperationInfo プロパティに移動し、省略記号をクリックして [操作の選択] ダイアログ ボックスを開きます。

  10. 右上隅の [インポート] をクリックします。

  11. [型] タブで [<現在のプロジェクト>] を強調表示します。

  12. 型リストから IWorkflow1 を選択して [OK] をクリックします。

    [操作の選択] ダイアログ ボックスに、コントラクトと操作に関する情報が代入されます。この情報は、テンプレートで定義され、WorkflowServiceTutorial プロジェクトに実装されています。

  13. [使用可能な操作]StartupService を強調表示し、[OK] をクリックします。

    デザイナは、TypedOperationInfo オブジェクトを作成し、コントラクトおよび操作の情報を設定し、それを ServiceOperationInfo プロパティで SendActivity アクティビティに関連付けることによって、SendActivity アクティビティを StartupService 操作に関連付けます。

  14. ワークフロー デザイナで [プロパティ] ペインに移動します。

  15. ChannelToken プロパティで ChannelToken オブジェクトの名前を作成し、Enter キーを押します。

  16. ChannelToken プロパティを展開します。

  17. EndpointName プロパティの場合、クライアントの App.config ファイルに移動します。サービスへのアクセスに使用するエンドポイントの名前をコピーして貼り付けます。たとえば、次のコードのエンドポイント名は "WSHttpContextBinding_IWorkflow1" です。

    <client>
        <endpoint address="https://localhost:8080/ServerWorkflow" binding="wsHttpContextBinding"
            bindingConfiguration="WSHttpContextBinding_IWorkflow1" contract="ServiceReference.IWorkflow1"
            name="WSHttpContextBinding_IWorkflow1">
            <identity>
                <userPrincipalName value="someone@example.com" />
            </identity>
        </endpoint>
    </client>
    
    Bb924504.note(ja-jp,VS.90).gifメモ :
    App.config ファイルの EndpointName プロパティと name 属性は同じである必要があります。同じでないと、クライアント アプリケーションを実行したときにエラーが発生します。

  18. OwnerActivityName プロパティの場合は、空白にしておきます。名前を選択しないと、コンパイル時にルート アクティビティの名前が選択されます。

  19. [プロパティ] ペインで [イベント] ボタンをクリックします。

  20. AfterResponse イベントのテキスト ボックスをダブルクリックして、イベント ハンドラを生成します。

  21. 次のコードを入力すると、StartupService 操作が呼び出されたときに、次のメッセージがユーザーに表示されます。

    Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
    private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
    {
        Console.WriteLine("A service instance has successfully been created.");
    }
    
  22. ワークフロー デザイナで、さらに 5 つの SendActivity アクティビティを追加します。

  23. SendActivity アクティビティを 1 つの操作、および手順 13. ~ 17. で使用したものと同じクライアント チャネル トークンに関連付けます。

  24. 算術演算 (加算、減算、乗算、除算) は n1 という名前の int を使用するため、n1 のアクティビティのバインドを作成するか、その値を設定する必要があります。このチュートリアルでは、ワークフローの既存のプロパティにバインドします。これを行うには、Workflow1.cs (Visual Basic ソリューションを作成した場合は Workflow1.vb) を開き、次の手順を実行します。

    1. Workflow1 クラスの名前を ClientWorkflow に変更します。

    2. 次の例のように、ClientWorkflow クラス定義にパブリック プロパティを作成します。

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
      
          Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
              Console.WriteLine("A service instance has successfully been created.")
          End Sub
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      
          private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
          {
              Console.WriteLine("A service instance has successfully been created.");
          }
      }
      
    3. ワークフロー デザイナを開き、加算演算の呼び出しに関連付けられた SendActivity アクティビティの [プロパティ] ペインで、省略記号をクリックします。そして、[既存のメンバへのバインド] タブから inputValue を選択して、inputValuen1 アクティビティのプロパティにバインドします。

    4. BeforeSend イベントのイベント ハンドラを実装して、サービスに送信するメッセージを作成します。

      Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
          inputValue = 1
          Console.WriteLine("The initial input value is {0}", inputValue)
      End Sub
      
      private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
      {
          inputValue = 1;
          Console.WriteLine("The initial input value is {0}", inputValue);
      }
      
  25. サービスからの結果を表示するには、演算が成功したときに戻り値を保持する変数を作成する必要があります。これを行うには、Workflow1.cs (Visual Basic ソリューションを作成した場合は Workflow1.vb) を開き、次の手順を実行します。

    1. 次の例のように、ClientWorkflow クラス定義に returnedValue という名前のパブリック プロパティを作成します。

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
          Public returnedValue As Integer = Nothing
      ...
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
          public int returnedValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      ...
      }
      
    2. ワークフロー デザイナを開き、[プロパティ] ペインで、省略記号をクリックします。そして、[既存のメンバへのバインド] タブから returnedValue を選択して、returnedValue[(戻り値)] アクティビティ プロパティにバインドします。

    3. AfterResponse イベントのイベント ハンドラを実装して、サービスから送り返されたメッセージを表示します。

      private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
      {
          Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue); 
      }
      
  26. 他の各算術演算については、inputValue および returnedValue を、n1 および [(戻り値)] にそれぞれバインドします。

  27. 手順 24c. と 25c. で行った算術演算に関連付けられている残りの SendActivity アクティビティで、BeforeSend イベントと AfterResponse イベントのイベント ハンドラを実装します。ShutdownService 操作に関連付けられた SendActivity アクティビティのイベント ハンドラを含むすべてのイベント ハンドラの実装例を次に示します。

        Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
        Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 1
            Console.WriteLine("The initial input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity2_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity3_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 2
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity3_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity4_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 6
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity4_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity5_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 3
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity5_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity6_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The workflow service instance has been successfully shut down.")
        End Sub
    
        private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("A service instance has successfully been created.");
        }
    
        private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 1;
            Console.WriteLine("The initial input value is {0}", inputValue);
        }
    
        private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue);
        }
    
        private void sendActivity3_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 2;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity3_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue);
        }
    
        private void sendActivity4_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 6;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity4_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue);
        }
    
        private void sendActivity5_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 3;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity5_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue);
        }
    
        private void sendActivity6_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The workflow service instance has been successfully shut down.");
        }
    
  28. Program.cs (Visual Basic では Module1.vb) で、WorkflowRuntime で使用されているサービスのリストに ChannelManagerService を追加して、チャネルとチャネル ファクトリをキャッシュします。ChannelManagerService の使用は任意ですが、使用しない場合はチャネルがキャッシュされないため、サービスとの通信時にワークフローのすべての SendActivity アクティビティで新しいチャネル インスタンスが使用されます。

    Shared WaitHandle As New AutoResetEvent(False)
    
    Shared Sub Main()
        Using workflowRuntime As New WorkflowRuntime()
            AddHandler workflowRuntime.WorkflowCompleted, AddressOf OnWorkflowCompleted
            AddHandler workflowRuntime.WorkflowTerminated, AddressOf OnWorkflowTerminated
    
            ' Add ChannelManagerService to the list of services used by the WorkflowRuntime.
            Dim cms As ChannelManagerService = New ChannelManagerService()workflowRuntime.AddService(cms)
    
            Dim workflowInstance As WorkflowInstance
            workflowInstance = workflowRuntime.CreateWorkflow(GetType(ClientWorkflow))
            workflowInstance.Start()
            WaitHandle.WaitOne()
        End Using
    End Sub
    Shared Sub OnWorkflowCompleted(ByVal sender As Object, ByVal e As WorkflowCompletedEventArgs)
        Console.WriteLine("The client workflow has completed." + vbLf + "Press <Enter> to exit the client application.")
        Console.ReadLine()
        WaitHandle.Set()
    End Sub
    
    Shared Sub OnWorkflowTerminated(ByVal sender As Object, ByVal e As WorkflowTerminatedEventArgs)
        Console.WriteLine(e.Exception.Message)
        WaitHandle.Set()
    End Sub
    
    using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        AutoResetEvent waitHandle = new AutoResetEvent(false);
    
        // Add ChannelManagerService to the list of services used 
        // by the WorkflowRuntime.
        ChannelManagerService cms = new ChannelManagerService();    workflowRuntime.AddService(cms);
    
        workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) 
        {
            Console.WriteLine("The client workflow has completed. \nPress <Enter> to exit the client application."); 
            Console.ReadLine(); 
            waitHandle.Set(); 
        };
    
        workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };
    
        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowServiceClient.ClientWorkflow));
        instance.Start();
    
        waitHandle.WaitOne();
    }
    
  29. 演習 1 で作成した WorkflowServiceTutorial ソリューションのワークフロー サービスにクライアントを使用するには、WorkflowServiceTutorial プロジェクト プロパティからコマンド ライン引数を削除する必要があります。これを行うには、次の手順を実行します。

    1. WorkflowServiceTutorial プロジェクト ノードを右クリックし、[プロパティ] をクリックします。
    2. [デバッグ] タブをクリックし、[開始オプション] の詳細ペインで、テキスト ボックスから /client:"WfcTestClient.exe" を削除します。
  30. WorkflowServiceTutorial ソリューション ノードを右クリックし、[プロパティ] をクリックします。

  31. [プロパティ ページ] ダイアログ ボックスで、[マルチ スタートアップ プロジェクト] をオンにします。

  32. WorkflowServiceTutorial がリストの一番上の項目として表示されない場合は、リスト ボックスの横の矢印をクリックして、一番上の項目にします。これは、クライアント アプリケーションがサービス上の操作を呼び出す前にサービスの実行を開始できるようにするために必要です。

  33. リストの各プロジェクトのアクションを [なし] から [開始] に変更します。

  34. [適用] をクリックしてから [OK] をクリックします。

  35. Visual Basic ソリューションを作成した場合は、[ソリューション エクスプローラ] ペインで WorkflowServiceClient プロジェクト ノードを右クリックし、[プロパティ] をクリックします。

  36. [アプリケーション] タブをクリックし、[ルート名前空間] テキスト ボックスから WorkflowServiceClient を削除します。削除しないと、クライアントが誤った名前空間を参照するため、ワークフロー サービスに接続できなくなります。

  37. ワークフロー サービス ソリューションをビルドして実行します。

  38. サービスを開始すると、クライアント アプリケーションが実行されます。コマンド プロンプトからクライアント アプリケーションを実行する場合は、次の点に注意してください。

    A workflow service instance has successfully been created.
    The initial input value is 1
    The value after invoking the Add operation is 1
    The new input value is 2
    The value after invoking the Subract operation is -1
    The new input value is 6
    The value after invoking the Multiply operation is -6
    The new input value is 3
    The value after invoking the Divide operation is -2
    The workflow service instance has been successfully shut down.
    The client workflow has completed. 
    Press <Enter> to exit the client application.
    

関連項目

その他の技術情報

演習 1: 基本ワークフロー サービスの作成

Copyright © 2007 by Microsoft Corporation. All rights reserved.