Поделиться через


Как реализовать асинхронного клиента веб-службы при помощи метода обратного вызова

Этот раздел посвящен технологии прежних версий. Веб-службы XML и клиенты веб-служб XML должны создаваться с использованием Windows Communication Foundation.

Технология обратного вызова представляет собой один из способов реализации асинхронного обмена данными между клиентом веб-службы и методом веб-службы, даже если этот метод предназначен для синхронного доступа. Данная технология рассматривается в разделе "Асинхронный обмен данными с XML-веб-службами".

Этот пример основан на классе веб-службы PrimeFactorizer с методом Factorize, для которого программа Wsdl.exe создала два асинхронных прокси-метода клиента, BeginFactorize и EndFactorize.

Реализация технологии обратного вызова

  1. Определите функцию обратного вызова, реализующую делегат AsyncCallback.

    public static void FactorizeCallback(IAsyncResult ar)
    
    Public Shared Sub FactorizeCallback(ar As IAsyncResult)
    
  2. Создайте экземпляр делегата AsyncCallback.

    AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback);
    
    Dim cb as AsyncCallback 
    cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback)
    
  3. Вызовите метод Begin, передав функцию обратного вызова в качестве второго аргумента и объект, предоставляющий состояние (в данном примере — клиентская реализация PrimeFactorizer), в качестве третьего аргумента.

    IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);
    
    Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, _
                                                         cb, pf)
    
  4. Проверьте свойство IsCompleted объекта IAsyncResult, возвращенного методом Begin. Значение true устанавливается после того, как клиент получил ответ от сервера.

  5. В функции обратного вызова обратитесь к объекту состояния. Свойство AsyncState параметра IAsyncState содержит объект, переданный в качестве третьего параметра методу Begin.

    PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState;
    
    Dim pf As PrimeFactorizer = ar.AsyncState
    
  6. В функции обратного вызова вызовите метод End для объекта состояния, полученного на предыдущем шаге.

    long[] results = pf.EndFactorize(ar);
    
    Dim results() as Long
    results = pf.EndFactorize(ar)
    

Пример

using System;
using System.Runtime.Remoting.Messaging;
using MyFactorize;

class TestCallback
 {           
      public static void Main(){
            long factorizableNum = 12345;
            PrimeFactorizer pf = new PrimeFactorizer();

            //Instantiate an AsyncCallback delegate to use as a parameter
            //in the BeginFactorize method.
            AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback);

          // Begin the Async call to Factorize, passing in our
          // AsyncCalback delegate and a reference
          // to our instance of PrimeFactorizer.
            IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);
            
            // Keep track of the time it takes to complete the async call
            // as the call proceeds.
         int start = DateTime.Now.Second;
         int currentSecond = start;
         while (!ar.IsCompleted){
            if (currentSecond < DateTime.Now.Second) {
                  currentSecond = DateTime.Now.Second;
                  Console.WriteLine("Seconds Elapsed..." + (currentSecond - start).ToString() );
            }
         }
         // Once the call has completed, you need a method to ensure the
         // thread executing this Main function 
         // doesn't complete prior to the call-back function completing.
         Console.Write("Press Enter to quit");
         int quitchar = Console.Read();
      }
      // Set up a call-back function that is invoked by the proxy class
      // when the asynchronous operation completes.
      public static void FactorizeCallback(IAsyncResult ar)
      {
          // You passed in our instance of PrimeFactorizer in the third
          // parameter to BeginFactorize, which is accessible in the
          // AsyncState property.
          PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState;
          long[] results;

          // Get the completed results.
            results = pf.EndFactorize(ar);
          
          //Output the results.
            Console.Write("12345 factors into: ");
            int j;
            for (j = 0; j<results.Length;j++){
                  if (j == results.Length - 1)
                      Console.WriteLine(results[j]);
                  else 
                      Console.Write(results[j] + ", ");
            }
      }
}
Imports System
Imports System.Runtime.Remoting.Messaging
Imports MyFactorize

Public Class TestCallback
    Public Shared Sub Main()
       Dim factorizableNum As Long = 12345
       Dim pf As PrimeFactorizer = new PrimeFactorizer()

       'Instantiate an AsyncCallback delegate to use as a 
       'parameter
       ' in the BeginFactorize method.
       Dim cb as AsyncCallback 
       cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback)

     ' Begin the Async call to Factorize, passing in the
     ' AsyncCallback delegate and a reference to our instance
     ' of PrimeFactorizer.
       Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, _
                                                     cb, pf)
            
     ' Keep track of the time it takes to complete the async call as
     ' the call proceeds.
       Dim start As Integer = DateTime.Now.Second
       Dim currentSecond As Integer = start
       Do while (ar.IsCompleted = false)
          If (currentSecond < DateTime.Now.Second) Then
                currentSecond = DateTime.Now.Second
                Console.WriteLine("Seconds Elapsed..." + 
                      (currentSecond - start).ToString() )
          End If
       Loop

      ' Once the call has completed, you need a method to ensure the
      ' thread executing this Main function 
      ' doesn't complete prior to the callback function completing.
       Console.Write("Press Enter to quit")
       Dim quitchar As Integer = Console.Read()
    End Sub

    ' Set up the call-back function that is invoked by the proxy 
    ' class when the asynchronous operation completes.
    Public Shared Sub FactorizeCallback(ar As IAsyncResult)
    
       ' You passed in the instance of PrimeFactorizer in the third
       ' parameter to BeginFactorize, which is accessible in the
       ' AsyncState property.
         Dim pf As PrimeFactorizer = ar.AsyncState
         Dim results() as Long

       ' Get the completed results.
         results = pf.EndFactorize(ar)
        
       'Output the results.
         Console.Write("12345 factors into: ")
         Dim j as Integer
         For j = 0 To results.Length - 1
              If  j = (results.Length - 1) Then
                   Console.WriteLine(results(j) )
              Else 
                   Console.Write(results(j).ToString + ", ")
              End If
        Next j         
     End Sub      
End Class

См. также

Задачи

Как реализовать асинхронный клиент веб-службы при помощи технологии ожидания
Как выполнить асинхронный вызов из клиента веб-службы

Основные понятия

Асинхронное взаимодействие с XML-веб-службами
Создание клиентов XML-веб-службы

Другие ресурсы

Создание клиентов для XML-веб-служб