<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    精彩的人生

    好好工作,好好生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

    ?

    在網絡中為了保證數據的實時性,需要對數據進行異步操作。Java Web Service和J2EE中的異步操作通過java消息機制來完成,消息機制是非常完善的技術了。而Microsoft的Web Service的異步功能是怎樣完成的呢?怎樣才能達到java的境地呢?當然,Microsoft有自己的一套。

    眾所周知,Web Service是靠SOAP協議進行數據傳輸的。而SOAP是基于XML技術之上的。SOAP協議是連接客戶和服務器的橋梁。而SOAP協議本身沒有異步功能,需要在客戶端實現異步調用。我們以一個簡單的Web Service的例子來說明這一點。

    一、MathService.asmx

    <%@ WebService Language="C#" Class="MathService" %>

    using System;

    using System.Web.Services;

    [WebService]

    public class MathService : WebService {

    [WebMethod]

    public float Add(float a, float b)

    {

    return a + b;

    }

    [WebMethod]

    public double Subtract(double a, double b)

    {

    return a - b;

    }

    [WebMethod]

    public float Multiply(float a, float b)

    {

    return a * b;

    }

    [WebMethod]

    public float Divide(float a, float b)

    {

    if (b==0) return -1;

    return a / b;

    }

    }

    這是個實現了加,減,乘,除的Web Service,任何客戶端程序都可以調用它。下面我們用wsdl(微軟公司提供)工具產生一個MathService.asmx 的客戶代理程序:wsdl /n:MyMath http://localhost/mathservice.asmx (假設MathService.asmx放在IIS服務器的根目錄) ,產生一個MathService.cs代理程序,默認是SOAP協議。

    二、MathService.cs:

    namespace MyMath{

    using System.Diagnostics;

    using System.Xml.Serialization;

    using System;

    using System.Web.Services.Protocols;

    using System.ComponentModel;

    using System.Web.Services;

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute("code")]

    [System.Web.Services.WebServiceBindingAttribute(Name="MathServiceSoap", Namespace="http://tempuri.org/")]

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

    public MathService() {

    this.Url = "http://localhost/mathservice.asmx";

    }

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Add", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

    public System.Single Add(System.Single a, System.Single b) {

    object[] results = this.Invoke("Add", new object[] {

    a,

    b});

    return ((System.Single)(results[0]));

    }

    public System.IAsyncResult BeginAdd(System.Single a, System.Single b, System.AsyncCallback callback, object asyncState) {

    return this.BeginInvoke("Add", new object[] {

    a,

    b}, callback, asyncState);

    }

    /// <remarks/>

    public System.Single EndAdd(System.IAsyncResult asyncResult) {

    object[] results = this.EndInvoke(asyncResult);

    return ((System.Single)(results[0]));

    }

    /// <remarks/>

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Subtract", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

    public System.Double Subtract(System.Double a, System.Double b) {

    object[] results = this.Invoke("Subtract", new object[] {

    a,

    b});

    return ((System.Double)(results[0]));

    }

    /// <remarks/>

    public System.IAsyncResult BeginSubtract(System.Double a, System.Double b, System.AsyncCallback callback, object asyncState) {

    return this.BeginInvoke("Subtract", new object[] {

    a,

    b}, callback, asyncState);

    }

    /// <remarks/>

    public System.Double EndSubtract(System.IAsyncResult asyncResult) {

    object[] results = this.EndInvoke(asyncResult);

    return ((System.Double)(results[0]));

    }

    /// <remarks/>

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Multiply", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

    public System.Single Multiply(System.Single a, System.Single b) {

    object[] results = this.Invoke("Multiply", new object[] {

    a,

    b});

    return ((System.Single)(results[0]));

    }

    /// <remarks/>

    public System.IAsyncResult BeginMultiply(System.Single a, System.Single b, System.AsyncCallback callback, object asyncState) {

    return this.BeginInvoke("Multiply", new object[] {

    a,

    b}, callback, asyncState);

    }

    /// <remarks/>

    public System.Single EndMultiply(System.IAsyncResult asyncResult) {

    object[] results = this.EndInvoke(asyncResult);

    return ((System.Single)(results[0]));

    }

    /// <remarks/>

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Divide", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

    public System.Single Divide(System.Single a, System.Single b) {

    object[] results = this.Invoke("Divide", new object[] {

    a,

    b});

    return ((System.Single)(results[0]));

    }

    /// <remarks/>

    public System.IAsyncResult BeginDivide(System.Single a, System.Single b, System.AsyncCallback callback, object asyncState) {

    return this.BeginInvoke("Divide", new object[] {

    a,

    b}, callback, asyncState);

    }

    /// <remarks/>

    public System.Single EndDivide(System.IAsyncResult asyncResult) {

    object[] results = this.EndInvoke(asyncResult);

    return ((System.Single)(results[0]));

    }

    }

    }

    之后我們用csc /t:library MathService.cs編譯并產生一個MathService.dll.

    現在我們可以寫任何的客戶程序去調用服務器上的MathService.asmx。

    如:WinForm, C#,ASPX等。

    下面我們寫一個test.cs去測試異步調用:

    三、test.cs:

    using System;

    public class test{

    public static void Main(){

    MyMath.MathService math = new MyMath.MathService();

    IAsyncResult result1 = math.BeginAdd(10,20,null,null);

    Object result=math.EndAdd(result1);

    Console.WriteLine("result =========="+result);

    }

    }

    我們看到它是先調用代理MathService.cs中的BeginAdd方法,然后狀態信息保存在IasyncResult中,直到調用了EndAdd方法才返回調用的確切值。本例是遠端調用MathService.asmx中的Add方法。

    那Microsoft到底怎樣實現客戶端的異步呢?設計模式又是怎樣的呢?

    異步模式所提供的革新之一就是調用方確定特定調用是否應是異步的。  對于被調用的對象,沒有必要執行附加的編程來用于支持其客戶端的異步行為;在該模式中異步委托提供此功能。公共語言運行庫處理調用方和被調用的對象視圖之間的差異。被調用的對象可以選擇顯式支持異步行為,這或者是因為它可以比一般結構更為有效地實現異步行為,或者是因為它想只支持其調用方的異步行為。但是,建議這種被調用的對象遵循公開異步操作的異步設計模式。

    類型安全是異步模式的另一項革新。尤其對于異步委托,針對 .NET 框架和公共語言運行庫的語言編譯器可令映射到規則 Invoke 方法的開始和結束操作(例如,BeginInvoke 和 EndInvoke)的方法簽名是類型安全的。這是十分重要的,因為編譯器為異步委托將同步調用拆分成開始和結束操作,使其能夠只傳遞有效參數。

    在此模式中所蘊含的基本想法如下所示:

    1.調用方確定特定調用是否應是異步的。

    2. 對于被調用的對象,沒有必要由其客戶端執行附加的編程來用于支持異步行為。公共語言運行庫結構應該能夠處理調用方和被調用的對象視圖之間的差異。

    3. 被調用的對象可以選擇顯式支持異步行為,這或者是因為它可以比一般結構更為有效地實現異步行為,或者是因為它想只支持其調用方的異步行為。但是,建議這種被調用的對象遵循公開異步操作的異步設計模式。

    4. 編譯器為 BeginInvoke 和 EndInvoke 以及異步委托生成類型安全方法簽名。

    5. .NET 框架提供支持異步編程模型所需的服務。此類服務的部分列表示例是:

    (1)同步基元,例如監視器和閱讀器編寫器鎖定。

    (2)線程和線程池。

    (3)同步構造,例如支持等候對象的容器。

    (4)向基礎結構片(例如 IMessage 對象和線程池)公開。

    該模式將一個同步調用拆分成各構成部分:開始操作、結束操作和結果對象。考慮以下示例,在其中可能要用大量時間來完成 Factorize 方法。

    public class PrimeFactorizer

    {

    public bool Factorize(int factorizableNum, ref int primefactor1, ref int primefactor2)

    {

    // Determine whether factorizableNum is prime.

    // If is prime, return true. Otherwise, return false.

    // If is prime, place factors in primefactor1 and primefactor2.

    }

    }

    如果遵循異步模式,則類庫編寫器添加 BeginFactorize 和 EndFactorize方法,這兩個方法將同步操作拆分成兩個異步操作:

    public class PrimeFactorizer

    {

    public bool Factorize(

        int factorizableNum,

        ref int primefactor1,

        ref int primefactor2)

    {

    // Determine whether factorizableNum is prime.

    // if is prime, return true; otherwise return false.

    // if is prime palce factors in primefactor1 and primefactor2

    }

    public IAsyncResult BeginFactorize(

       int factorizableNum,

       ref int primefactor1,

       ref int primefactor2,

       AsyncCallback callback,

       Object state)

    {

     // Begin the factorizing asynchronously, and return a result object,

    }

    public bool EndFactorize(

       ref int primefactor1,

       ref int primefactor2,

       IAsyncResult asyncResult

     )

    {

    // End (or complete) the factorizing, and

    // return the results,

    // and obtain the prime factors.

    }

    }

    服務器將異步操作拆分成兩個邏輯部分:采用來自客戶端的輸入并調用異步操作的部分,向客戶端提供異步操作結果的部分。

    除了異步操作所需的輸入外,第一部分還采用在完成異步操作時后要被調用的 AsyncCallback 委托。第一部分返回一個可等待的對象,該對象實現客戶端使用的 IAsyncResult 接口來確定異步操作的狀態。

    服務器還利用它返回到客戶端的可等待的對象來維護與異步操作關聯的任何狀態。通過提供可等待的對象,客戶端使用第二部分獲取異步操作的結果。

    可用于客戶端來啟動異步操作的選項有:

    在開始異步調用時提供回調委托。

     public class Driver1

       {

         public PrimeFactorizer primeFactorizer;

         public void Results(IAsyncResult asyncResult)

        {

         int primefactor1=0;

          int primefactor2=0;

          bool prime = primeFactorizer.EndFactorize(

             ref primefactor1,

             ref primefactor2,

             asyncResult);

        }

         public void Work()

         {

          int factorizableNum=1000589023,

          int primefactor1=0;

          int primefactor2=0;

          Object state = new Object();

          primeFactorizer = new PrimeFactorizer();

          AsyncCallback callback = new Callback(this.Results);

          IAsyncResult asyncResult =                      primeFactorizer.BeginFactorize(

           factorizableNum,

           ref primefactor1,

           ref primefactor2,

           callback,

           state);

        } 

    在開始異步調用時不提供回調委托。

    public class Driver2

    {

    public static void Work()

    {

    int factorizableNum=1000589023,

    int primefactor1=0;

    int primefactor2=0;

    Object state = new Object();

    PrimeFactorizer primeFactorizer = new PrimeFactorizer();

    AsyncCallback callback = new Callback(this.Results);

    IAsyncResult asyncResult = primeFactorizer.BeginFactorize(

    factorizableNum,

    ref primefactor1,

    ref primefactor2,

    callback,

    state);

    bool prime = primeFactorizer.EndFactorize(

    ref primefactor1,

    ref primefactor2,

    asyncResult);

    }

    }

    我們以.Net的一個例子來說明這一點:

    AsyncDelegate2.cs

    using System;

    using System.Threading;

    using System.Runtime.Remoting;

    using System.Runtime.Remoting.Messaging;

    public class Wak

    {

    public int Pat(int i)

    {

    Console.WriteLine("Hash: {0} Wak Pat", Thread.CurrentThread.GetHashCode());

    return i*2;

    }

    };

    public delegate int WakPatDelegate(int i);// 異步調用的委派.

    public class Simple

    {

    public static void SomeMethod(IAsyncResult ar)

    {

    // Obtain value from AsyncState object

    int value = Convert.ToInt32(ar.AsyncState);

    // Obtain results via EndInvoke

    int result = ((WakPatDelegate)((AsyncResult)ar).AsyncDelegate ).EndInvoke(ar);

    Console.WriteLine("Simple.SomeMethod (AsyncCallback): Result of {0} in Wak.Pak is {1} ",value, result);

    }

    public static void Main(String[] args)

    {

    Console.WriteLine("Thread Simple Context Sample");

    Console.WriteLine("");

    Console.WriteLine("Make an instance of a context-bound type Wak");

    Wak oWak = new Wak();

    int value=0;

    int result=0;

    Console.WriteLine("Make a sync call on the object");

    value = 10;

    result = oWak.Pat(value);

    Console.WriteLine("Result of {0} in Wak.Pak is {1} ",value, result);

    Console.WriteLine("Make single Async call on Context-bound object");

    WakPatDelegate wpD1 = new WakPatDelegate(oWak.Pat);

    value = 20;

    IAsyncResult ar1 = wpD1.BeginInvoke(value,null,null);

    ar1.AsyncWaitHandle.WaitOne();

    result = wpD1.EndInvoke(ar1);

    Console.WriteLine("Result of {0} in Wak.Pak is {1} ",value, result);

    Console.WriteLine("Make single Async call on Context-bound object - use AsyncCallback and StateObject");

    WakPatDelegate wpD2 = new WakPatDelegate(oWak.Pat);

    value = 30;

    IAsyncResult ar2 = wpD2.BeginInvoke(

    value,

    new AsyncCallback(Simple.SomeMethod),

    value

    );

    Console.WriteLine("Make multiple Async calls on Context-bound object");

    int asyncCalls = 5;

    IAsyncResult[] ars = new IAsyncResult[asyncCalls];

    WaitHandle[] whs = new WaitHandle[asyncCalls];

    int[] values = new int[asyncCalls];

    WakPatDelegate wpD3 = new WakPatDelegate(oWak.Pat);

    for (int i=0; i < asyncCalls; i++)

    {

    values[i] = i;

    ars[i] = wpD3.BeginInvoke(values[i],null,null);

    whs[i] = ars[i].AsyncWaitHandle;

    }

    WaitHandle.WaitAll(whs,1000, false);

    for (int i=0; i < asyncCalls; i++)

    {

    result = wpD3.EndInvoke(ars[i]);

    Console.WriteLine("Result of {0} in Wak.Pak is {1} ",values[i], result);

    }

    Console.WriteLine("");

    Console.WriteLine("Done");

    }

    }

        

    如果異步調用成功,將顯示:

    Thread Simple Context Sample

    Make an instance of a context-bound type Wak

    Make a sync call on the object

    Hash: 3 Wak Pat

    Result of 10 in Wak.Pak is 20

    Make single Async call on Context-bound object

    Hash: 16 Wak Pat

    Result of 20 in Wak.Pak is 40

    Make single Async call on Context-bound object - use AsyncCallback and StateObje

    ct

    Hash: 16 Wak Pat

    Make multiple Async calls on Context-bound object

    Simple.SomeMethod (AsyncCallback): Result of 30 in Wak.Pak is 60

    Hash: 16 Wak Pat

    Hash: 16 Wak Pat

    Hash: 16 Wak Pat

    Hash: 16 Wak Pat

    Hash: 16 Wak Pat

    Result of 0 in Wak.Pak is 0 

    Result of 1 in Wak.Pak is 2

    Result of 2 in Wak.Pak is 4

    Result of 3 in Wak.Pak is 6

    Result of 4 in Wak.Pak is 8

    Done

    原文地址:http://www.ccw.com.cn/htm/center/prog/02_8_23_6.asp

    posted on 2006-05-07 16:28 hopeshared 閱讀(2688) 評論(1)  編輯  收藏 所屬分類: Web Service

    Feedback

    # re: 轉:Web Service 的異步調用 2008-08-26 15:08 toni
    好東東  回復  更多評論
      

    主站蜘蛛池模板: 亚洲AV无码乱码精品国产| 日韩毛片免费在线观看| 国产成人综合亚洲AV第一页 | 久久亚洲中文无码咪咪爱| 成年人网站在线免费观看| 亚洲一卡2卡4卡5卡6卡残暴在线| 69视频在线观看高清免费| 亚洲精品视频专区| 欧洲乱码伦视频免费| 亚洲国产乱码最新视频| 好吊妞在线新免费视频| 国产精品亚洲一区二区在线观看| 免费观看亚洲人成网站| h视频免费高清在线观看| 亚洲成AV人在线播放无码| 亚洲免费在线视频观看| 日韩亚洲人成在线| 亚洲A∨精品一区二区三区| 国产JIZZ中国JIZZ免费看| 亚洲成a人片在线观看日本| 免费看片在线观看| 最新亚洲人成无码网www电影| 亚洲一区日韩高清中文字幕亚洲| 一二三区免费视频| 亚洲欧洲日产国产综合网| 美女网站免费福利视频| 免费精品国产自产拍在线观看 | 成人免费视频网站www| 亚洲精品无码aⅴ中文字幕蜜桃| mm1313亚洲精品无码又大又粗| 在线人成免费视频69国产| 亚洲一区二区三区91| 亚洲人成色77777在线观看大| 久久精品免费观看国产| 亚洲精品国产精品| 国产亚洲AV无码AV男人的天堂| 波多野结衣在线免费视频| 日本中文字幕免费看| 91天堂素人精品系列全集亚洲| 免费毛片网站在线观看| 国产真人无码作爱免费视频|