回调技术是一种可实现与 Web 服务方法进行异步通信的 Web 服务客户端的方法(虽然该方法可能用于同步访问)。 将在主题“与 XML Web services 进行异步通信”中解释该技术。
此示例基于具有 Factorize 方法的 Web 服务类 PrimeFactorizer,Wsdl.exe 工具已经为该类生成了两个异步客户端代理方法:BeginFactorize 和 EndFactorize。
实现回调技术
- 定义一个实现 AsyncCallback 委托的回调函数。 - public static void FactorizeCallback(IAsyncResult ar)- Public Shared Sub FactorizeCallback(ar As IAsyncResult)
- 实例化 AsyncCallback 委托。 - AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback);- Dim cb as AsyncCallback cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback)
- 调用 Begin 方法,将回调函数作为第二个参数传递,将提供状态的对象(在此示例中为 PrimeFactorizer 的客户端实现)作为第三个参数传递。 - IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);- Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, _ cb, pf)
- 检查 Begin 方法返回的 IAsyncResult 上的 IsCompleted 属性。 在客户端收到来自服务器的响应后,值被设置为 true。 
- 在回调函数内,访问状态对象。 IAsyncState 参数的 AsyncState 属性将传递的对象作为 Begin 方法的第三个参数。 - PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState;- Dim pf As PrimeFactorizer = ar.AsyncState
- 在回调函数内,对在上一个步骤中获得的状态对象调用 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
请参见
任务
如何:使用等待技术实现异步 Web 服务客户端
如何:从 Web 服务客户端进行异步调用
概念
与 XML Web services 进行异步通信
生成 XML Web services 客户端
其他资源
.gif)
版权所有 (C) 2007 Microsoft Corporation。保留所有权利。