Megosztás a következőn keresztül:


Útmutató: A WCF szolgáltatásműveletek aszinkron meghívása

Ez a cikk azt ismerteti, hogyan férhet hozzá az ügyfél aszinkron módon egy szolgáltatásművelethez. A jelen cikkben szereplő szolgáltatás implementálja a ICalculator felületet. Az ügyfél az eseményvezérelt aszinkron hívási modell használatával aszinkron módon hívhatja meg a műveleteket ezen a felületen. (További információ az eseményalapú aszinkron hívásmodellről: Többszálú programozás az eseményalapú aszinkron mintával). Egy olyan példa, amely bemutatja, hogyan implementálhat egy műveletet aszinkron módon egy szolgáltatásban, olvassa el a How to: Implement an Asynchronous Service Operation (Aszinkron szolgáltatásművelet implementálása) című témakört. A szinkron és aszinkron műveletekről további információt a Szinkron és az Aszinkron műveletek című témakörben talál.

Feljegyzés

Az eseményvezérelt aszinkron hívásmodell nem támogatott ChannelFactory<TChannel>. Az aszinkron hívások csatorna-előállító használatával történő indításáról további információt a ChannelFactory<TChannel>Következő témakörben talál : Hívási műveletek aszinkron módon a Channel Factory használatával.

Eljárás

WCF szolgáltatásműveletek aszinkron meghívása

  1. Futtassa a ServiceModel Metadata Utility Tool (Svcutil.exe) eszközt a parancsbeállítások és a /async/tcv:Version35 parancsok együttes használatával az alábbi parancsban látható módon.

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

    Ez a szinkron és standard delegáltalapú aszinkron műveletek mellett létrehoz egy WCF-ügyfélosztályt, amely a következőket tartalmazza:

    • Két <operationName>Async művelet az eseményalapú aszinkron hívási megközelítéshez. Példa:

      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
      
    • A művelet befejeződött az űrlap <operationName>Completed eseményalapú aszinkron hívási megközelítéssel való használatához. Példa:

      public event System.EventHandler<AddCompletedEventArgs> AddCompleted;
      
      Public Event AddCompleted As System.EventHandler(Of AddCompletedEventArgs)
      
    • System.EventArgs típusok minden művelethez (az űrlaphoz <operationName>CompletedEventArgs) az eseményalapú aszinkron hívási megközelítéssel való használatra. Példa:

      [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. A hívó alkalmazásban hozzon létre egy visszahívási metódust, amelyet az aszinkron művelet befejezésekor kell meghívni, ahogyan az az alábbi mintakódban látható.

    // 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. A művelet meghívása előtt használjon egy új típusú általános System.EventHandler<TEventArgs>>EventArgsoperationName<típust a kezelő metódus (az előző lépésben létrehozott) hozzáadásához az <operationName>Completed eseményhez. Ezután hívja meg a metódust<>operationNameAsync. Példa:

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

Példa

Feljegyzés

Az eseményalapú aszinkron modell tervezési irányelvei szerint ha egynél több értéket ad vissza, a rendszer egy értéket ad vissza tulajdonságként Result , a többit pedig tulajdonságokként az EventArgs objektumon. Ennek egyik eredménye, hogy ha egy ügyfél az eseményalapú aszinkron parancsbeállítások használatával importál metaadatokat, és a művelet több értéket ad vissza, az alapértelmezett EventArgs objektum egy értéket ad vissza tulajdonságként Result , a többi pedig az EventArgs objektum tulajdonságait. Ha tulajdonságként szeretné megkapni az Result üzenetobjektumot, és a visszaadott értékeket tulajdonságokként szeretné megkapni az objektumon, használja a parancsbeállítást /messageContract . Ez létrehoz egy aláírást, amely visszaadja a válaszüzenetet az Result objektum tulajdonságaként EventArgs . Ezután az összes belső visszatérési érték a válaszüzenet-objektum tulajdonságai.

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

Lásd még