Číst v angličtině

Sdílet prostřednictvím


Postupy: Asynchronní volání operací služby WCF

Tento článek popisuje, jak může klient přistupovat k operaci služby asynchronně. Služba v tomto článku implementuje ICalculator rozhraní. Klient může operace v tomto rozhraní volat asynchronně pomocí asynchronního volajícího modelu řízeného událostmi. (Další informace o asynchronním volajícím modelu založeném na událostech najdete v tématu Vícevláknové programování pomocí asynchronního vzoru založeného na událostech). Příklad, který ukazuje, jak implementovat operaci asynchronně ve službě, viz Postupy: Implementace asynchronní operace služby. Další informace o synchronních a asynchronních operacích naleznete v tématu Synchronní a asynchronní operace.

Poznámka

Asynchronní volání řízené událostmi není podporováno při použití ChannelFactory<TChannel>. Informace o provádění asynchronních volání pomocí nástroje ChannelFactory<TChannel>, naleznete v tématu Postupy: Volání operací asynchronně pomocí objektu pro vytváření kanálů.

Postup

Asynchronní volání operací služby WCF

  1. Spusťte nástroj ServiceModel Metadata Utility Tool (Svcutil.exe) se společnými možnostmi /async příkazů, /tcv:Version35 jak je znázorněno v následujícím příkazu.

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

    To generuje kromě synchronních a standardních asynchronních operací založených na delegátech také klientskou třídu WCF, která obsahuje:

    • Dvě <operationName>``Async operace pro použití s asynchronním voláním založeným na událostech. Příklad:

      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);
      }
      
    • Operace dokončených událostí formuláře <operationName>``Completed pro použití s asynchronním voláním založeným na událostech. Příklad:

      public event System.EventHandler<AddCompletedEventArgs> AddCompleted;
      
    • System.EventArgs typy pro každou operaci (formuláře <operationName>``CompletedEventArgs) pro použití s asynchronním voláním založeným na událostech. Příklad:

      [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]));
              }
          }
      }
      
  2. V volající aplikaci vytvořte metodu zpětného volání, která se má volat při dokončení asynchronní operace, jak je znázorněno v následujícím vzorovém kódu.

    // Asynchronous callbacks for displaying results.
    static void AddCallback(object sender, AddCompletedEventArgs e)
    {
        Console.WriteLine($"Add Result: {e.Result}");
    }
    
  3. Před voláním operace pomocí nového obecného System.EventHandler<TEventArgs> typu <operationName>``EventArgs přidejte do události metodu obslužné rutiny (vytvořenou v předchozím kroku <operationName>``Completed ). Pak zavolejte metodu <operationName>``Async . Příklad:

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

Příklad

Poznámka

Pokyny k návrhu pro stav asynchronního modelu založeného na událostech, že pokud je vrácena více než jedna hodnota, vrátí se jedna hodnota jako Result vlastnost a ostatní se vrátí jako vlastnosti objektu EventArgs . Jedním z těchto výsledků je, že pokud klient importuje metadata pomocí možností asynchronního příkazu založeného na událostech a operace vrátí více než jednu hodnotu, výchozí EventArgs objekt vrátí jednu hodnotu jako Result vlastnost a zbytek jsou vlastnosti objektu EventArgs . Pokud chcete přijmout objekt zprávy jako Result vlastnost a mít vrácené hodnoty jako vlastnosti tohoto objektu /messageContract , použijte možnost příkazu. Tím se vygeneruje podpis, který vrátí zprávu odpovědi jako Result vlastnost objektu EventArgs . Všechny interní návratové hodnoty jsou vlastnosti objektu zprávy odpovědi.

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({value1},{value2})");

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

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

            // Divide
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine($"Divide({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: {e.Result}");
        }

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

Viz také