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

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

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

    精彩的人生

    好好工作,好好生活

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

    深入學(xué)習(xí)Web Service系列之 異步開(kāi)發(fā)模式

    ——《深入學(xué)習(xí) Web Service 系列》之一

    Terrylee 2005 12 4

    概述

    在本篇隨筆中,通過(guò)一些簡(jiǎn)單的示例來(lái)說(shuō)一下 Web Service 中的異步調(diào)用模式。調(diào)用 Web Service 方法有兩種方式,同步調(diào)用和異步調(diào)用。同步調(diào)用是程序繼續(xù)執(zhí)行前等候調(diào)用的完成,而異步調(diào)用在后臺(tái)繼續(xù)時(shí),程序也繼續(xù)執(zhí)行,不必等待方法處理完成而直接返回。具體的調(diào)用流程見(jiàn)下圖:

    ?

    對(duì)于同步調(diào)用方法而言, UI 線程依賴于方法的實(shí)現(xiàn),方法執(zhí)行時(shí)間過(guò)長(zhǎng)將導(dǎo)致 UI 無(wú)法及時(shí)與用戶進(jìn)行交互。我們知道,在 Windows 客戶端中,每個(gè)進(jìn)程都有單一的 UI 進(jìn)程,在服務(wù)器中,可擴(kuò)展性依賴于線程的使用。對(duì)于異步調(diào)用方法而言,能夠及時(shí)于用戶交互響應(yīng),從而提供了良好的用戶體驗(yàn);同時(shí)也可以改善服務(wù)器的可擴(kuò)展性,將服務(wù)器與通訊問(wèn)題隔離。

    客戶端異步調(diào)用方法

    在客戶端異步調(diào)用是完全基于 Proxy 的方法,異步行為最簡(jiǎn)單的模式。 Visual Studio WSDL.EXE 提供對(duì)它的直接支持。所以我們不必在 Web 服務(wù)應(yīng)用程序中編寫(xiě)額外的代碼來(lái)處理異步調(diào)用。

    遍及 .NET Framework 的異步調(diào)用有一個(gè)基礎(chǔ)的設(shè)計(jì)模式: Begin 方法和 End 方法,他們分別用于開(kāi)始和終止異步處理。 Visual Studio WSDL.exe 生成了這兩種方法:

    Begin<WebServiceMethodName> ——該方法通知 Web 服務(wù)開(kāi)始處理調(diào)用,并立即返回。該方法不返回 Web 服務(wù)調(diào)用所指定的數(shù)據(jù)類型,而是返回一種實(shí)現(xiàn) IasyncResult 接口的數(shù)據(jù)類型。

    End<WebServiceMethodName> ——該方法通知 Web 服務(wù)返回先前啟動(dòng)的 Web 方法所生成的結(jié)果。

    IasyncResult 接口包含了 WaitHandle 類型的 AsyncWaitHandle 特性。這個(gè)公共接口允許用戶的客戶應(yīng)用程序等待調(diào)用,而且,該接口將用 Any All 語(yǔ)義(例如 WaitHandle.WaitOne WaitAny WaitAll )作為信號(hào)通知客戶應(yīng)用程序。例如,如果想要客戶應(yīng)用程序異步等候一個(gè) Web 方法,可調(diào)用 WaitOne 來(lái)處理要完成的 Web 服務(wù)。

    一般來(lái)說(shuō),客戶端異步代理方法有兩種實(shí)現(xiàn)機(jī)制:使用同步對(duì)象和回調(diào)機(jī)制(也許你可能對(duì)用這個(gè)詞不習(xí)慣,實(shí)在找不到第二個(gè)詞來(lái)代替,暫且這樣稱呼吧)

    同步對(duì)象

    同步對(duì)象允許用戶對(duì) Web 服務(wù)的方法進(jìn)行調(diào)用(使用 Begin 方法),然后繼續(xù)處理。在后面的程序中,可以調(diào)用 End 方法,傳遞同步對(duì)象,以便得到調(diào)用結(jié)果。這種方式下,能夠繼續(xù)執(zhí)行函數(shù)中的程序流程,而不執(zhí)行回調(diào)處理。在這里 調(diào)用 WaitOne() 方法會(huì)掛起當(dāng)前線程,避免忙等待的發(fā)生,直到 Web Services 方法調(diào)用結(jié)束返回后,該線程才會(huì)被重新喚起。

    示例代碼:

    ?1 /// ? <summary>
    ?2 /// ?利用同步對(duì)象實(shí)現(xiàn)異步調(diào)用
    ?3 /// ? </summary>
    ?4 /// ? <param?name="sender"></param>
    ?5 /// ? <param?name="e"></param>

    ?6 private ? void ?btn_AsyncClient_Click( object ?sender,?System.EventArgs?e)
    ?7 {
    ?8 ????IAsyncResult?ar? = ?wsc.BeginHello( this .txt_UserName.Text,? null ,? null );
    ?9
    10
    11 ????MessageBox.Show( " Continue?to?do?some?other?things " );
    12
    13 ????ar.AsyncWaitHandle.WaitOne();
    14
    15 ????strHello? = ?wsc.EndHello(ar);
    16
    17 ???? this .rtb_Result.Text? = ?strHello;
    18 }

    回調(diào)機(jī)制

    從本質(zhì)上說(shuō),異步回調(diào)機(jī)制是委托的 .NET 等價(jià)物,它通過(guò)在異步操作完成時(shí)建立一個(gè)被調(diào)用的單獨(dú)方法來(lái)進(jìn)行工作。調(diào)用應(yīng)用程序能夠繼續(xù)處理其他的任務(wù),直到回調(diào)函數(shù)被調(diào)用為止。這就意味著處理已經(jīng)完成了,應(yīng)用程序可以正常運(yùn)行了。使用同步對(duì)象不同于回調(diào)機(jī)制的區(qū)別是,當(dāng)檢查 Web 方法是否已經(jīng)完成,以及檢查 Web 方法中是否含有需要的結(jié)果時(shí),我們無(wú)法對(duì)其進(jìn)行控制,而在回調(diào)的情況中, Web 方法一旦完成,這些工作就會(huì)被自動(dòng)執(zhí)行。

    示例代碼:

    ?1 /// ? <summary>
    ?2 /// ?顯示結(jié)果
    ?3 /// ? </summary>
    ?4 /// ? <param?name="sender"></param>
    ?5 /// ? <param?name="e"></param>

    ?6 public ? void ?UpdateResult( object ?sender,?EventArgs?e)
    ?7 {
    ?8 ???? this .rtb_Result.Text? = ?strHello;
    ?9 }

    10
    11 public ? void ?OnHelloComplete(IAsyncResult?ar)
    12 {
    13 ????strHello? = ?wsc.EndHello(ar);
    14
    15 ???? this .rtb_Result.Invoke( new ?EventHandler(UpdateResult));
    16 }

    17
    18 /// ? <summary>
    19 /// ?用回調(diào)機(jī)制實(shí)現(xiàn)異步調(diào)用
    20 /// ? </summary>
    21 /// ? <param?name="sender"></param>
    22 /// ? <param?name="e"></param>

    23 private ? void ?btn_CallBack_Click( object ?sender,?System.EventArgs?e)
    24 {
    25 ????AsyncCallback?cb? = ? new ?AsyncCallback(OnHelloComplete);
    26
    27 ????wsc.BeginHello( this .txt_UserName.Text,?cb,? null );
    28 }

    使用回調(diào)機(jī)制還是同步對(duì)象取決于用戶所面臨的具體情況。在檢查異步調(diào)用是否完成時(shí),如果愿意對(duì)處理過(guò)程進(jìn)行控制,那么可以選擇使用同步對(duì)象。如果覺(jué)得自己編寫(xiě)代碼來(lái)完成對(duì) Web 服務(wù)的調(diào)用,且當(dāng)方法一旦執(zhí)行完畢就立即由所調(diào)用的特殊函數(shù)來(lái)處理所返回的結(jié)果更適合一些,那么就更適合用回調(diào)機(jī)制。

    在客戶端使用異步方法調(diào)用,可以改進(jìn) UI 響應(yīng)度,在服務(wù)器端不需要實(shí)現(xiàn)異步操作,對(duì)服務(wù)器來(lái)說(shuō)是透明的,而且客戶端能夠在任何時(shí)間選擇阻塞。

    服務(wù)端使用 Soap One-Way 方法

    在服務(wù)器端使用 One-Way 方法實(shí)現(xiàn)異步調(diào)用,其實(shí)質(zhì)是將單項(xiàng)消息發(fā)送到端點(diǎn)。這種方式的特點(diǎn)是方法沒(méi)有返回值,客戶端方法不會(huì)從調(diào)用的服務(wù)器端方法中收到返回值;我們無(wú)法判斷方法結(jié)束的時(shí)間,對(duì)于結(jié)果需要顯式通知或者輪詢。

    Web 服務(wù)端,我們使用 [SoapDocumentMethod] 定義 One-Way 方法:

    ?[System.Web.Services.Protocols.SoapDocumentMethod(OneWay = true )]

    示例代碼:

    ?1 /// ? <summary>
    ?2 /// ?One-Way方式的異步調(diào)用Set
    ?3 /// ? </summary>
    ?4 /// ? <param?name="sender"></param>
    ?5 /// ? <param?name="e"></param>

    ?6 private ? void ?btn_OneWay_Click( object ?sender,?System.EventArgs?e)
    ?7 {
    ?8 ????wsc.SetHello( this .txt_UserName.Text);????
    ?9 }

    10
    11 /// ? <summary>
    12 /// ?One-Way方式的異步調(diào)用Get
    13 /// ? </summary>
    14 /// ? <param?name="sender"></param>
    15 /// ? <param?name="e"></param>

    16 private ? void ?btn_onewayGet_Click( object ?sender,?System.EventArgs?e)
    17 {
    18 ????strHello? = ?wsc.GetHello();
    19
    20 ???? this .rtb_Result.Text? = ?strHello;
    21 }

    One-Way 方法不適合于下列情況:

    l???????? 方法需要對(duì)結(jié)果輪詢

    l???????? 方法需要同步

    服務(wù)端使用 WSE SoapSender SoapRecevier

    在進(jìn)行本部分內(nèi)容之前,我們需要安裝 WSE2.0 WSE 支持面向消息的編程,為我們提供了 SoapSender SoapReceiver 基類,它能夠支持發(fā)送和接收 SoapEnvelopes ,同時(shí)它也通過(guò) SoapClient SoapService 提供了更多的事務(wù)支持。 SoapSender SoapReceiver 在客戶端和服務(wù)端同時(shí)實(shí)現(xiàn),客戶端使用 SoapSender 發(fā)送消息,同時(shí)可選擇使用 SoapReceiver 接收消息;服務(wù)端使用 SoapReceiver 接收消息,同時(shí)也可以選擇使用 SoapSender 發(fā)送通知和回應(yīng)。

    示例代碼:

    ?客戶端:

    ?1 /// ? <summary>
    ?2 ???? /// ?自定義的消息接收類
    ?3 ???? /// ? </summary>

    ?4 ???? public ? class ?MyReceiver:?SoapReceiver
    ?5 ???? {
    ?6 ???????? public ? static ?Form1?form;
    ?7 ???????? private ? string ?strBody;
    ?8
    ?9 ???????? protected ? override ? void ?Receive(SoapEnvelope?envelope)
    10 ???????? {
    11 ????????????strBody? = ?envelope.InnerText;
    12
    13 ???????????? /// 注意:在進(jìn)行此項(xiàng)之前,一定要把rtb_Result控件的屬性設(shè)為Public
    14 ????????????form.rtb_Result.Invoke( new ?EventHandler(UpdateBody));
    15 ????????}

    16
    17 ???????? void ?UpdateBody( object ?sender,?System.EventArgs?e)
    18 ???????? {
    19 ????????????form.rtb_Result.Text? = ?strBody;
    20 ????????}

    21 ????}

    1 /// ? <summary>
    2 /// ?用WSE實(shí)現(xiàn)異步調(diào)用
    3 /// ? </summary>
    4 /// ? <param?name="sender"></param>
    5 /// ? <param?name="e"></param>

    6 private ? void ?button4_Click( object ?sender,?System.EventArgs?e)
    7 {
    8 ????wsc.FireEvent();
    9 }

    Web Service端:

    ?1 private ?ArrayList?Listeners
    ?2 ???????? {
    ?3 ???????????? get
    ?4 ???????????? {
    ?5 ???????????????? return ?(ArrayList)Application[ " Listeners " ];
    ?6 ????????????}

    ?7 ????????}

    ?8
    ?9 ????????[WebMethod]
    10 ???????? public ? void ?AddListener( string ?listener)
    11 ???????? {
    12 ????????????ArrayList?alist? = ?(ArrayList)Application[ " Listeners " ];
    13
    14 ???????????? if (alist? == ? null )
    15 ????????????????alist? = ? new ?ArrayList();
    16
    17 ????????????alist.Add(listener);
    18
    19 ????????????Application[ " Listeners " ]? = ?alist;
    20
    21 ????????}

    22
    23 ????????[WebMethod]
    24 ???????? public ? void ?FireEvent()
    25 ???????? {
    26 ???????????? int ?i;
    27
    28 ???????????? for (i? = ? 0 ;i? < ? this .Listeners.Count;i ++ )
    29 ???????????? {
    30 ????????????????SoapEnvelope?envelope? = ? new ?SoapEnvelope();
    31
    32 ????????????????envelope.SetBodyObject( " Hello?World! " );
    33
    34 ????????????????envelope.Context.Addressing.Action? = ? new ?Action(( string )( this .Listeners[i]));
    35
    36 ????????????????envelope.Context.Addressing.ReplyTo? = ? new ?ReplyTo( new ?System.Uri(( string )( this .Listeners[i])));
    37
    38 ????????????????SoapSender?peerProxy? = ? new ?SoapSender( new ?System.Uri(( string )( this .Listeners[i])));
    39
    40 ????????????????peerProxy.Send(envelope);
    41 ????????????}

    42 ????????}

    服務(wù)端使用 WSE 自定義 SoapMSMQ 傳輸

    SoapMSMQ 是一款開(kāi)源軟件,簡(jiǎn)化使用 WSE 進(jìn)行 MSMQ 操作,下載地址:

    http://www.codeproject.com/useritems/SoapMSMQ.asp

    SoapMSMQ 完全支持事務(wù),具有如下特點(diǎn):

    l???????? 在事務(wù)中,請(qǐng)求要被同步初始化

    l???????? 同步階段排隊(duì)請(qǐng)求,并且返回令牌

    l???????? 異步階段處理各個(gè)事務(wù)

    l???????? 所有持有令牌的請(qǐng)求都保證會(huì)被處理,但可能會(huì)不成功

    l???????? 支持向客戶端發(fā)送通知

    對(duì) SoapMSMQ 感興趣的朋友可以下載下來(lái)后,做進(jìn)一步的研究。

    總結(jié)

    異步方法調(diào)用改善了客戶端的響應(yīng)和用戶體驗(yàn),增加了服務(wù)端的可擴(kuò)展性。當(dāng)方法需要耗費(fèi)大量的時(shí)間時(shí),可以采用異步方式調(diào)用,提供系統(tǒng)并發(fā)處理的能力。對(duì)于異步方式的開(kāi)發(fā),我們可以有如上所述的廣泛選擇。

    示例程序界面:

    下載地址:

    http://www.cnblogs.com/Files/Terrylee/AsyncDemo.rar

    原文地址:http://terrylee.cnblogs.com/archive/2005/12/05/290845.html

    posted on 2006-05-07 15:28 hopeshared 閱讀(779) 評(píng)論(0)  編輯  收藏 所屬分類: Web Service
    主站蜘蛛池模板: 亚洲精品国自产拍在线观看| 免费观看亚洲人成网站| 国产a级特黄的片子视频免费| 亚洲情XO亚洲色XO无码| 亚洲H在线播放在线观看H| 免费VA在线观看无码| 精品无码国产污污污免费网站| 日本一道本高清免费| 亚洲av激情无码专区在线播放| 亚洲成a人片在线观看天堂无码| a在线视频免费观看| 麻豆国产VA免费精品高清在线 | 亚洲中文字幕无码专区| 亚洲冬月枫中文字幕在线看| 日本免费精品一区二区三区| 在线观看成人免费视频不卡| 中文字幕精品无码亚洲字 | 中文字幕亚洲男人的天堂网络| 美女网站在线观看视频免费的| 成年大片免费视频| 久久精品国产亚洲AV网站| 色噜噜噜噜亚洲第一| 国产在线观看麻豆91精品免费| 亚洲中文字幕无码中文字在线| 亚洲成AV人影片在线观看| 91香焦国产线观看看免费| 国产精品亚洲mnbav网站 | 一级特黄特色的免费大片视频| 亚洲人成电影网站免费| 亚洲av鲁丝一区二区三区| 一本到卡二卡三卡免费高| 天天看片天天爽_免费播放| 日韩精品亚洲人成在线观看| 国产精品福利片免费看| 国产又粗又长又硬免费视频| 亚洲日本在线免费观看| 久久免费国产视频| 国产亚洲AV手机在线观看| 添bbb免费观看高清视频| 女人张开腿给人桶免费视频 | 亚洲欧洲av综合色无码 |