方法: WCF サービス操作を非同期的に呼び出すHow to: Call WCF Service Operations Asynchronously

ここでは、クライアントからサービス操作に非同期にアクセスする方法について説明します。This topic covers how a client can access a service operation asynchronously. このトピックのサービスは、ICalculator インターフェイスを実装しています。The service in this topic implements the ICalculator interface. クライアントは、イベント ドリブンの非同期呼び出しモデルを使用して、このインターフェイスで操作を非同期に呼び出すことができます The client can call the operations on this interface asynchronously by using the event-driven asynchronous calling model. (イベント ベースの非同期呼び出しモデルの詳細については、次を参照してください。イベント ベースの非同期パターンを使用したマルチ スレッド プログラミング)。(For more information about the event-based asynchronous calling model, see Multithreaded Programming with the Event-based Asynchronous Pattern). サービスで操作を非同期的に実装する方法の例を参照してください方法。非同期サービス操作を実装します。For an example that shows how to implement an operation asynchronously in a service, see How to: Implement an Asynchronous Service Operation. 同期および非同期操作の詳細については、次を参照してください。同期および非同期操作します。For more information about synchronous and asynchronous operations, see Synchronous and Asynchronous Operations.

注意

ChannelFactory<TChannel> を使用している場合、イベント ドリブンの非同期呼び出しモデルはサポートされません。The event-driven asynchronous calling model is not supported when using a ChannelFactory<TChannel>. 使用して非同期呼び出しを行う方法については、ChannelFactory<TChannel>を参照してください方法。チャネル ファクトリを使用して非同期的に操作を呼び出すします。For information about making asynchronous calls using the ChannelFactory<TChannel>, see How to: Call Operations Asynchronously Using a Channel Factory.

プロシージャProcedure

WCF サービス操作を非同期に呼び出すにはTo call WCF service operations asynchronously

  1. 実行、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe)両方のツール、/async/tcv:Version35次のコマンドで示すように、このコマンド オプションをまとめてします。Run the ServiceModel Metadata Utility Tool (Svcutil.exe) tool with both the /async and the /tcv:Version35 command options together as shown in the following command.

    svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples http://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35  
    

    これは、クラスを生成、だけでなく、同期操作と標準的なデリゲートに基づく非同期操作、WCF クライアントが含まれています。This generates, in addition to the synchronous and standard delegate-based asynchronous operations, a WCF client class that contains:

    • 2 つ <operationName > Async -イベント ベースの非同期呼び出し方法で使用するための操作。Two <operationName>Async operations for use with the event-based asynchronous calling approach. 例:For example:

      public void AddAsync(double n1, double n2)
      {
          this.AddAsync(n1, n2, null);
      }
      
      public void AddAsync(double n1, double n2, object userState)
      {
          if ((this.onBeginAddDelegate == null))
          {
              this.onBeginAddDelegate = new BeginOperationDelegate(this.OnBeginAdd);
          }
          if ((this.onEndAddDelegate == null))
          {
              this.onEndAddDelegate = new EndOperationDelegate(this.OnEndAdd);
          }
          if ((this.onAddCompletedDelegate == null))
          {
              this.onAddCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnAddCompleted);
          }
          base.InvokeAsync(this.onBeginAddDelegate, new object[] {
                      n1,
                      n2}, this.onEndAddDelegate, this.onAddCompletedDelegate, userState);
      }
      
      Public Overloads Sub AddAsync(ByVal n1 As Double, ByVal n2 As Double)
          Me.AddAsync(n1, n2, Nothing)
      End Sub
      
      Public Overloads Sub AddAsync(ByVal n1 As Double, ByVal n2 As Double, ByVal userState As Object)
          If (Me.onBeginAddDelegate Is Nothing) Then
              Me.onBeginAddDelegate = AddressOf Me.OnBeginAdd
          End If
          If (Me.onEndAddDelegate Is Nothing) Then
              Me.onEndAddDelegate = AddressOf Me.OnEndAdd
          End If
          If (Me.onAddCompletedDelegate Is Nothing) Then
              Me.onAddCompletedDelegate = AddressOf Me.OnAddCompleted
          End If
          MyBase.InvokeAsync(Me.onBeginAddDelegate, New Object() {n1, n2}, Me.onEndAddDelegate, Me.onAddCompletedDelegate, userState)
      End Sub
      
    • フォームの操作完了イベント <operationName > Completed -イベント ベースの非同期呼び出し方法を使用します。Operation completed events of the form <operationName>Completed for use with the event-based asynchronous calling approach. 例:For example:

      public event System.EventHandler<AddCompletedEventArgs> AddCompleted;
      
      Public Event AddCompleted As System.EventHandler(Of AddCompletedEventArgs)
      
    • System.EventArgs 各操作の種類 (形式の <operationName>CompletedEventArgs) - イベント ベースの非同期呼び出し方法を使用します。System.EventArgs types for each operation (of the form <operationName>CompletedEventArgs) for use with the event-based asynchronous calling approach. 例:For example:

      [System.Diagnostics.DebuggerStepThroughAttribute()]
      [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
      public partial class AddCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
      {
          private object[] results;
          
          public AddCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
                  base(exception, cancelled, userState)
          {       this.results = results;         }
          
          public double Result
          {
              get            {
                  base.RaiseExceptionIfNecessary();
                  return ((double)(this.results[0]));
              }
          }
      }
      
      <System.Diagnostics.DebuggerStepThroughAttribute(),  _
       System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")>  _
      Partial Public Class AddCompletedEventArgs
          Inherits System.ComponentModel.AsyncCompletedEventArgs
          
          Private results() As Object
          
          Public Sub New(ByVal results() As Object, ByVal exception As System.Exception, ByVal cancelled As Boolean, ByVal userState As Object)
              MyBase.New(exception, cancelled, userState)
              Me.results = results
          End Sub
          
          Public ReadOnly Property Result() As Double
              Get
                  MyBase.RaiseExceptionIfNecessary
                  Return CType(Me.results(0),Double)
              End Get
          End Property
      End Class
      
  2. 次のサンプル コードに示すように、呼び出し元アプリケーションで、非同期操作の完了時に呼び出されるコールバック メソッドを作成します。In the calling application, create a callback method to be called when the asynchronous operation is complete, as shown in the following sample code.

    // Asynchronous callbacks for displaying results.
    static void AddCallback(object sender, AddCompletedEventArgs e)
    {
        Console.WriteLine("Add Result: {0}", e.Result);
    }
    
    ' Asynchronous callbacks for displaying results.
    Private Shared Sub AddCallback(ByVal sender As Object, ByVal e As AddCompletedEventArgs)
    
        Console.WriteLine("Add Result: {0}", e.Result)
    
    End Sub
    
  3. 操作を呼び出す前に、新しいジェネリックを使用してSystem.EventHandler<TEventArgs>型の <operationName > EventArgs (前の手順で作成した) ハンドラー メソッドを追加して、<operationName > Completedイベント。Prior to calling the operation, use a new generic System.EventHandler<TEventArgs> of type <operationName>EventArgs to add the handler method (created in the preceding step) to the <operationName>Completed event. まず、<operationName > Asyncメソッド。Then call the <operationName>Async method. 例:For example:

    // AddAsync
    double value1 = 100.00D;
    double value2 = 15.99D;
    client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
    client.AddAsync(value1, value2);
    Console.WriteLine("Add({0},{1})", value1, value2);
    
    ' AddAsync
    Dim value1 As Double = 100
    Dim value2 As Double = 15.99
    AddHandler client.AddCompleted, AddressOf AddCallback
    client.AddAsync(value1, value2)
    Console.WriteLine("Add({0},{1})", value1, value2)
    

Example

注意

イベント ベースの非同期モデルのデザイン ガイドラインには、複数の値を返す場合に、1 つの値を Result プロパティとして返し、残りの値を EventArgs オブジェクトのプロパティとして返すことが記載されています。The design guidelines for the event-based asynchronous model state that if more than one value is returned, one value is returned as the Result property and the others are returned as properties on the EventArgs object. この 1 つの結果として、クライアントがイベント ベースの非同期コマンド オプションを使用してメタデータをインポートし、操作から複数の値が返される場合、既定の EventArgs オブジェクトが 1 つの値を Result プロパティとして返し、残りの値は EventArgs オブジェクトのプロパティになります。メッセージ オブジェクトを Result プロパティとして受け取り、返された値をそのオブジェクトのプロパティとして取得する場合は、/messageContract コマンド オプションを使用します。One result of this is that if a client imports metadata using the event-based asynchronous command options and the operation returns more than one value, the default EventArgs object returns one value as the Result property and the remainder are properties of the EventArgs object.If you want to receive the message object as the Result property and have the returned values as properties on that object, use the /messageContract command option. これにより、Result オブジェクトの EventArgs プロパティとして応答メッセージを返すシグネチャが生成されます。This generates a signature that returns the response message as the Result property on the EventArgs object. すべての内部戻り値は、応答メッセージ オブジェクトのプロパティになります。All internal return values are then properties of the response message object.

using System;

namespace Microsoft.ServiceModel.Samples
{
    // The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

    class Client
    {
        static void Main()
        {
            Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
            Console.WriteLine();

            // Create a client
            CalculatorClient client = new CalculatorClient();

            // AddAsync
            double value1 = 100.00D;
            double value2 = 15.99D;
            client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
            client.AddAsync(value1, value2);
            Console.WriteLine("Add({0},{1})", value1, value2);

            // SubtractAsync
            value1 = 145.00D;
            value2 = 76.54D;
            client.SubtractCompleted += new EventHandler<SubtractCompletedEventArgs>(SubtractCallback);
            client.SubtractAsync(value1, value2);
            Console.WriteLine("Subtract({0},{1})", value1, value2);

            // Multiply
            value1 = 9.00D;
            value2 = 81.25D;
            double result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Divide
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            Console.ReadLine();

            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
        }

        // Asynchronous callbacks for displaying results.
        static void AddCallback(object sender, AddCompletedEventArgs e)
        {
            Console.WriteLine("Add Result: {0}", e.Result);
        }

        static void SubtractCallback(object sender, SubtractCompletedEventArgs e)
        {
            Console.WriteLine("Subtract Result: {0}", e.Result);
        }
    }
}
Imports System

Namespace Microsoft.ServiceModel.Samples

    ' The service contract is defined in generatedClient.vb, generated from the service by the svcutil tool.

    Class Client

        Public Shared Sub Main()

            Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.")
            Console.WriteLine()

            ' Create a client
            Dim client As New CalculatorClient()

            ' AddAsync
            Dim value1 As Double = 100
            Dim value2 As Double = 15.99
            AddHandler client.AddCompleted, AddressOf AddCallback
            client.AddAsync(value1, value2)
            Console.WriteLine("Add({0},{1})", value1, value2)

            ' SubtractAsync
            value1 = 145
            value2 = 76.54
            AddHandler client.SubtractCompleted, AddressOf SubtractCallback
            client.SubtractAsync(value1, value2)
            Console.WriteLine("Subtract({0},{1})", value1, value2)

            ' Multiply
            value1 = 9
            value2 = 81.25
            Dim result As Double = client.Multiply(value1, value2)
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)

            ' Divide
            value1 = 22
            value2 = 7
            result = client.Divide(value1, value2)
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result)
            Console.ReadLine()

            'Closing the client gracefully closes the connection and cleans up resources
            client.Close()

        End Sub
        ' Asynchronous callbacks for displaying results.
        Private Shared Sub AddCallback(ByVal sender As Object, ByVal e As AddCompletedEventArgs)

            Console.WriteLine("Add Result: {0}", e.Result)

        End Sub
        Private Shared Sub SubtractCallback(ByVal sender As Object, ByVal e As SubtractCompletedEventArgs)

            Console.WriteLine("Subtract Result: {0}", e.Result)

        End Sub

    End Class

End Namespace

関連項目See also