<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      ASP.NET創建XML Web服務全接觸(10)

      [摘要]和XML Web服務異步地通訊  和一個XML Web服務異步通訊遵循被Microsoft.NET Framework其它部分使用的異步設計模式。然而,在你取得那些細節之前,重要的是注意一個XML Web服務不必特意的寫來處理用于異步調用的異步請求。你使用Wsdl.exe為你的客戶端創建的代理類自...

          

        和XML Web服務異步地通訊

        和一個XML Web服務異步通訊遵循被Microsoft.NET Framework其它部分使用的異步設計模式。然而,在你取得那些細節之前,重要的是注意一個XML Web服務不必特意的寫來處理用于異步調用的異步請求。你使用Wsdl.exe為你的客戶端創建的代理類自動地創建用于異步調用XML Web服務方法的方法。即使只有一個XML Web服務方法的同步實現也是這樣的。

        .NET Framework異步方法調用設計模式

        用于調用異步方法的設計模式,尤其是用于.NET Framework,針對每個同步方法分別有兩個異步方法。對每個同步方法,都有一個Begin異步方法和一個End異步方法。Begin方法被客戶端調用來開始方法調用。也就是說,客戶端指示這個方法來開始處理方法調用,但是立即返回。End方法被客戶端調用來取得XML Web服務方法調用執行的處理結果。

        一個客戶端如何知道何時調用End方法?.NET Framework定義了兩種方法來實現客戶端判斷其時間。第一種是傳送一個回調函數到Begin方法,當方法已經完成處理的時候調用。第二個方法是使用WaitHandle類的一個方法來導致客戶端等待方法完成。當一個客戶端實現第二個方法,并且調用Begin方法,返回值不是XML Web服務方法指定的數據類型,而是一個實現IAsyncResult接口的類型。IAsyncResult接口包含一個WaitHandle類型的AsyncWaitHandle屬性,實現支持等待同步對象變為帶有WaitHandle.WaitOne、WaitAny和WaitAll標記的方法。當一個同步對象被標記的時候,它指示等待特定的資源的線程可以訪問資源的。如果一個XML Web服務客戶端使用wait方法僅僅異步地調用一個XML Web服務方法,那么它可以調用WaitOne來等待XML Web服務方法完成處理。

        重要的是注意不管客戶端選擇來與XML Web服務異步通訊的兩種方法中的哪一種,SOAP消息發送和接收都與同步通信時吻合。也就是說,只有一個SOAP請求和SOAP響應通過網絡發送和接收。代理類通過使用一個不同的線程而不是客戶端用來調用Begin方法的線程來處理SOAP響應。因此,客戶端可以繼續執行線程上的其它的工作,而代理類處理接收和操作SOAP響應。

        實現一個產生異步的方法調用的XML Web服務客戶端

        用于從使用ASP.NET創建的XML Web服務客戶端產生一個到XML Web服務的異步調用的體系結構被嵌入.NET Framework和由Wsdl.exe構造的代理類中。用于異步調用的設計模式被.NET Framework定義,代理類提供和一個XML Web服務異步通信的機制。當一個用于XML Web服務的代理類被使用Wsdl.exe構造的時候,有三個方法分別被創建,用于XML Web服務中的公共XML Web服務方法。下面的表格描述那三個方法。

        代理類中的方法名 描述

       。糔ameOfWebServiceMethod> 同步發送用于名為<NameOfWebServiceMethod>的XML Web服務方法的消息。

        Begin<NameOfWebServiceMethod> 開始與名為<NameOfWebServiceMethod>的XML Web服務方法的異步消息通信。

        End<NameOfWebServiceMethod> 結束與名為<NameOfWebServiceMethod>的XML Web服務方法的異步消息通信,從XML Web服務方法中取得完成的消息。

        下面的代碼示例是一個XML Web服務方法,它可能花費相對長的時間來完成處理。因此,當你應該設置你的XML Web服務客戶端來異步地調用XML Web服務方法的時候,它是一個很好的示例。

      [C#]
      <%@ WebService Language="C#" Class="PrimeFactorizer" %>

      using System;
      using System.Collections;
      using System.Web.Services;

      class PrimeFactorizer {

       [WebMethod]
       public long[] Factorize(long factorizableNum){
        ArrayList outList = new ArrayList();
        long i = 0;
        int j;
        try{
         long Check = factorizableNum;

         //Go through every possible integer
         //factor between 2 and factorizableNum / 2.
         //Thus, for 21, check between 2 and 10.
         for (i = 2; i < (factorizableNum / 2); i++){
          while(Check % i == 0){
           outList.Add(i);
           Check = (Check/i);
          }
         }
         //Double-check to see how many prime factors have been added.
         //If none, add 1 and the number.
         j = outList.Count;
         if (j == 0) {
          outList.Add(1);
          outList.Add(factorizableNum);
         }
         j = outList.Count;

         //Return the results and
         //create an array to hold them.
         long[] primeFactor = new long[j];
         for (j = 0; j < outList.Count; j++){
          //Pass the values one by one, making sure
          //to convert them to type ulong.
          primeFactor[j] = Convert.ToInt64(outList[j]);
         }
         return primeFactor;
        }
        catch (Exception) {
         return null;
        }
       }
      }

      [Visual Basic]
      <%@ WebService Class="PrimeFactorizer" Language="VB" %>
      Imports System
      Imports System.Collections
      Imports System.Web.Services

      Public Class PrimeFactorizer
      <WebMethod> _
      Public Function Factorize(factorizableNum As Long) As Long()
       Dim outList As New ArrayList()
       Dim i As Long = 0
       Dim j As Integer
       Try
        Dim Check As Long = factorizableNum

        'Go through every possible integer
        'factor between 2 and factorizableNum / 2.
        'Thus, for 21, check between 2 and 10.
        For i = 2 To CLng(factorizableNum / 2) - 1
         While Check Mod i = 0
          outList.Add(i)
          Check = CLng(Check / i)
         End While
        Next i
        'Double-check to see how many prime factors have been added.
        'If none, add 1 and the number.
        j = outList.Count
        If j = 0 Then
         outList.Add(1)
         outList.Add(factorizableNum)
        End If
        j = outList.Count

        'Return the results and
        'create an array to hold them.
        Dim primeFactor(j - 1) As Long
        For j = 0 To outList.Count - 1
         'Pass the values one by one, making sure
         'to convert them to type ulong.
         primeFactor(j) = CLng(outList(j))
        Next j
        Return primeFactor
       Catch
        Return Nothing
       End Try
      End Function
      End Class


        下面的代碼示例是一個Wsdl.exe生成的代理類的一部分,用于上述XML Web服務方法。注意BeginFactorize和EndFactorize方法,因為它們被用來與Factorize XML Web服務方法異步通信。

      public class PrimeFactorizer : System.Web.Services.Protocols.SoapHttpClientProtocol {

       public long[] Factorize(long factorizableNum) {
        object[] results = this.Invoke("Factorize", new object[] { factorizableNum});
         return ((long[])(results[0]));
       }

       public System.IAsyncResult BeginFactorize(long factorizableNum, System.AsyncCallback callback, object  asyncState) {
        return this.BeginInvoke("Factorize", new object[] {
        factorizableNum}, callback, asyncState);
       }

       public long[] EndFactorize(System.IAsyncResult asyncResult) {
        object[] results = this.EndInvoke(asyncResult);
        return ((long[])(results[0]));
       }
      }


        有兩個方法用來和XML Web服務方法異步通信。下面的代碼示例說明了如何與一個XML Web服務方法異步通信,并且使用回調函數來取得XML Web服務方法的結果。

      [C#]
      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 == false){
         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] + ", ");
        }
       }
      }

      [Visual Basic]
      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 Web服務方法異步通信,然后使用一個同步對象來等待處理結束。

      [C#]
      // -----------------------------------------------------------------------// Async Variation 2.
      // Asynchronously invoke the Factorize method,
      //without specifying a call back.
      using System;
      using System.Runtime.Remoting.Messaging;
      // MyFactorize, is the name of the namespace in which the proxy class is
      // a member of for this sample.
      using MyFactorize;

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

        // Begin the Async call to Factorize.
        IAsyncResult ar = pf.BeginFactorize(factorizableNum, null, null);

        // Wait for the asynchronous operation to complete.
        ar.AsyncWaitHandle.WaitOne();

        // Get the completed results.
        long[] 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] + ", ");
        }
       }
      }

      [Visual Basic]
      Imports System
      Imports System.Runtime.Remoting.Messaging
      Imports MyFactorize ' Proxy class namespace

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

      ' Begin the Async call to Factorize.
      Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, Nothing, Nothing)

      ' Wait for the asynchronous operation to complete.
      ar.AsyncWaitHandle.WaitOne()

      ' Get the completed results.
      Dim results() as Long
      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


        注意:如果FactorizeCallback是一個需要同步化/線成親和上下文的上下文綁定類,那么回調被通過上下文分配體系結構來分配。換句話說,相對于它的對這樣的上下文的調用者,回調可能異步的執行。在方法標記上有單向修飾詞的精確的語義。這指的是任何這樣的方法調用可能同步地或異步地執行,相對于調用者,并且在執行控制返回給它的時候,調用者不能產生任何關于完成這樣一個調用的假設。
      而且,在異步操作完成之前調用EndInvoke將阻塞調用者。使用相同的AsyncResult再次調用它的行為是不確定的。

        Cancel方法是一個在過去一段特定時間之后取消方法處理的請求。注意它是一個客戶端的請求,并且最好服務器對此有所承諾。在接收到方法已經被取消的消息之后,客戶端就不必做服務器是否已經停止處理的假設了?蛻舳俗詈貌灰茐馁Y源,例如文件對象,因為服務器可能仍然需要使用它們。IAsyncResult實例的IsCompleted屬性在服務器結束它的處理之后將被設置為true,不再使用任何客戶端提供的資源。因此,IsCompleted屬性設置為true之后,客戶端就可以安全的銷毀資源了。





      日韩精品一区二区三区高清