Delen via


Procedure: WCF-servicebewerkingen asynchroon aanroepen

In dit artikel wordt beschreven hoe een client asynchroon toegang heeft tot een servicebewerking. De service in dit artikel implementeert de ICalculator interface. De client kan de bewerkingen op deze interface asynchroon aanroepen met behulp van het asynchrone asynchrone aanroepmodel op basis van gebeurtenissen. (Zie voor meer informatie over het asynchrone aanroepende model op basis van gebeurtenissenMultithreaded Programming met het Asynchrone patroon op basis van gebeurtenissen). Zie Een Asynchrone servicebewerking implementeren voor een voorbeeld dat laat zien hoe u een bewerking asynchroon implementeert in een service. Zie Synchrone en Asynchrone bewerkingen voor meer informatie over synchrone en asynchrone bewerkingen.

Notitie

Het asynchrone aanroepmodel op basis van gebeurtenissen wordt niet ondersteund wanneer u een ChannelFactory<TChannel>. Zie Procedure voor informatie over het maken van asynchrone aanroepen met behulp van de ChannelFactory<TChannel>instructies : Bewerkingen asynchroon aanroepen met behulp van een Channel Factory.

Procedure

WCF-servicebewerkingen asynchroon aanroepen

  1. Voer het hulpprogramma ServiceModel Metadata Utility (Svcutil.exe) uit met zowel de /async als de /tcv:Version35 opdrachtopties samen, zoals wordt weergegeven in de volgende opdracht.

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

    Dit genereert, naast de synchrone en standaard asynchrone asynchrone bewerkingen op basis van gedelegeerden, een WCF-clientklasse die:

    • Twee <operationName>``Async bewerkingen voor gebruik met de asynchrone aanroepbenadering op basis van gebeurtenissen. Voorbeeld:

      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
      
    • Bewerking voltooide gebeurtenissen van het formulier <operationName>``Completed voor gebruik met de asynchrone aanroepbenadering op basis van gebeurtenissen. Voorbeeld:

      public event System.EventHandler<AddCompletedEventArgs> AddCompleted;
      
      Public Event AddCompleted As System.EventHandler(Of AddCompletedEventArgs)
      
    • System.EventArgs typen voor elke bewerking (van het formulier <operationName>``CompletedEventArgs) voor gebruik met de asynchrone aanroepbenadering op basis van gebeurtenissen. Voorbeeld:

      [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. Maak in de aanroepende toepassing een callback-methode die moet worden aangeroepen wanneer de asynchrone bewerking is voltooid, zoals wordt weergegeven in de volgende voorbeeldcode.

    // 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. Voordat u de bewerking aanroept, gebruikt u een nieuw algemeen System.EventHandler<TEventArgs> type <operationName>``EventArgs om de handlermethode (gemaakt in de vorige stap) toe te voegen aan de <operationName>``Completed gebeurtenis. Roep vervolgens methode <operationName>``Async aan. Voorbeeld:

    // 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)
    

Opmerking

Notitie

De ontwerprichtlijnen voor de asynchrone modelstatus op basis van gebeurtenissen dat als er meer dan één waarde wordt geretourneerd, één waarde wordt geretourneerd als de Result eigenschap en de andere als eigenschappen voor het EventArgs object worden geretourneerd. Een resultaat hiervan is dat als een client metagegevens importeert met behulp van de asynchrone opdrachtopties op basis van gebeurtenissen en de bewerking meer dan één waarde retourneert, retourneert het standaardobject EventArgs één waarde als de Result eigenschap en de rest zijn eigenschappen van het EventArgs object. Als u het berichtobject wilt ontvangen als de Result eigenschap en de geretourneerde waarden als eigenschappen voor dat object wilt hebben, gebruikt u de /messageContract opdrachtoptie. Hiermee wordt een handtekening gegenereerd die het antwoordbericht retourneert als de Result eigenschap van het EventArgs object. Alle interne retourwaarden zijn vervolgens eigenschappen van het antwoordberichtobject.

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);
        }
    }
}
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

Zie ook