HOW TO:使用回呼技術實作非同步 Web 服務用戶端

回呼 (Callback) 技術是實作 Web 服務用戶端與 Web 服務方法進行非同步通訊 (儘管這個方法是要用於同步存取) 的一種方式。在<以非同步方式與 XML Web Service 通訊>主題中會說明這個技術。

這個範例是以具有 Factorize 方法的 Web 服務類別 PrimeFactorizer 為基礎,而 Wsdl.exe 工具已為此方法產生了兩個非同步用戶端 Proxy 方法 BeginFactorizeEndFactorize

若要實作回呼技術

  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. 針對 Begin 方法傳回的 IAsyncResult 檢查其 IsCompleted 屬性。這個值會在用戶端收到伺服器的回應之後設定為 true

  5. 在回呼函式中,存取狀態物件。IAsyncState 參數的 AsyncState 屬性含有當做第三個參數傳遞給 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

請參閱

工作

HOW TO:使用等候技術實作非同步 Web 服務用戶端
HOW TO:從 Web 服務用戶端發出非同步呼叫

概念

以非同步方式與 XML Web Service 通訊
建置 XML Web Service 用戶端

其他資源

建立 XML Web Service 的用戶端

Footer image

Copyright © 2007 by Microsoft Corporation. All rights reserved.