明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

服務(wù)器端異步 Web 方法(一)

[摘要]摘要:Matt Powell 介紹了如何在服務(wù)器端使用異步 Web 方法,來創(chuàng)建高性能的 Microsoft ASP.NET Web 服務(wù)。 簡介在九月份的第三篇專欄(英文)中,我談到了利用 Microsoft® .NET Framework 的客戶端功能通過 HTTP 異步調(diào)用 ...
摘要:Matt Powell 介紹了如何在服務(wù)器端使用異步 Web 方法,來創(chuàng)建高性能的 Microsoft ASP.NET Web 服務(wù)。

簡介

在九月份的第三篇專欄(英文)中,我談到了利用 Microsoft® .NET Framework 的客戶端功能通過 HTTP 異步調(diào)用 Web 服務(wù)的問題。這種調(diào)用 Web 服務(wù)的方法非常有用,使用時不必鎖定您的應(yīng)用程序或產(chǎn)生過多后臺線程,F(xiàn)在我們了解一下在服務(wù)器端提供類似功能的異步 Web 方法。異步 Web 方法在編寫 ISAPI 擴展方面具有與 HSE_STATUS_PENDING 方法類似的高性能,但不需要為管理自己的線程池編寫代碼,同時又具有以托管代碼方式運行的所有優(yōu)點。

首先我們考慮一下常規(guī)的同步 Microsoft® ASP.NET Web 方法。當(dāng)您從同步 Web 方法返回時,將發(fā)送對該方法的響應(yīng)。如果需要較長的時間來完成請求,則處理請求的線程會一直被占用,直到方法調(diào)用結(jié)束。不幸的是,多數(shù)較長的調(diào)用是由較長的數(shù)據(jù)庫查詢或?qū)α硪粋 Web 服務(wù)的調(diào)用等事件引起的。例如,如果您調(diào)用數(shù)據(jù)庫,當(dāng)前線程會一直等待調(diào)用完成。線程無事可做,只是等待,直至聽到查詢的返回。當(dāng)線程等待完成對 TCP 套接字或后端 Web 服務(wù)的調(diào)用時,也會出現(xiàn)類似的問題。

讓線程處于等待狀態(tài)很不好,特別是在服務(wù)器的運行壓力很大的情況下。等待中的線程不會進(jìn)行任何有效工作,例如為其他請求提供服務(wù)。我們需要找到一種方法,能夠在服務(wù)器上開始較長的后臺進(jìn)程,同時又能將當(dāng)前線程返回到 ASP.NET 進(jìn)程池。然后,當(dāng)較長的后臺進(jìn)程完成時,我們調(diào)用一個回調(diào)函數(shù),結(jié)束對請求的處理,并通過某種方式通知 ASP.NET 請求已完成。實際上,這種功能可由 ASP.NET 使用異步 Web 方法提供。

異步 Web 方法的工作原理

當(dāng)您使用 Web 方法編寫典型的 ASP.NET Web 服務(wù)時,Microsoft® Visual Studio® .Net 只是編譯您的代碼以創(chuàng)建程序集;當(dāng)收到對其 Web 方法的請求時,將調(diào)用該程序集。程序集本身并不知道關(guān)于 SOAP 的任何事情。因此,當(dāng)您的應(yīng)用程序首次啟動時,ASMX 處理程序必須反映您的程序集,以確定提供哪些 Web 方法。對于常規(guī)的同步請求,這些操作都很簡單:找出哪些方法具有關(guān)聯(lián)的 WebMethod 屬性、基于 SOAPAction HTTP 標(biāo)頭來設(shè)置調(diào)用正確方法的邏輯。

對于異步請求,在反映過程中,ASMX 處理程序?qū)ふ揖哂心撤N簽名并將簽名識別為異步的 Web 方法。該處理程序?qū)ふ曳弦韵乱?guī)則的方法對:

BeginXXX 和 EndXXX Web 方法,其中 XXX 是任意字符串,表示要提供的方法的名稱。
BeginXXX 函數(shù)返回一個 IAsyncResult 接口,并分別接受 AsyncCallback 和一個對象,作為其最后兩個輸入?yún)?shù)。
EndXXX 函數(shù)接受一個 IAsyncResult 接口,作為其唯一的參數(shù)。
兩個方法都必須使用 WebMethod 屬性進(jìn)行標(biāo)識。
如果 ASMX 處理程序發(fā)現(xiàn)兩個方法符合上述所有條件,則將方法 XXX 作為常規(guī)的 Web 方法在其 WSDL 中提供。該方法將接受在 BeginXXX 的簽名中的 AsyncCallback 參數(shù)之前定義的參數(shù)作為輸入,并返回由 EndXXX 函數(shù)返回的內(nèi)容。因此,如果某個 Web 方法具有如下同步聲明:

[WebMethod]

public string LengthyProcedure(int milliseconds) {...}

則異步聲明將為:

[WebMethod]

public IAsyncResult BeginLengthyProcedure(

int milliseconds,

AsyncCallback cb,

object s) {...}



[WebMethod]

public string EndLengthyProcedure(IAsyncResult call) {...}

每個方法的 WSDL 都是相同的。

在 ASMX 處理程序反映程序集并檢測到某個異步 Web 方法后,它必須以不同于處理同步請求的方式處理對該方法的請求。它將調(diào)用 BeginXXX 方法,而不是某個簡單方法。它將傳入的請求還原序列化到要傳遞到函數(shù)的參數(shù)中(與處理同步請求時一樣);但是它還將指針傳遞到一個內(nèi)部回調(diào)函數(shù)(作為 BeginXXX 方法的額外 AsyncCallback 參數(shù))。

這種方法類似于 .NET Framework 中 Web 服務(wù)客戶端應(yīng)用程序的異步編程模式。如果客戶端支持異步 Web 服務(wù)調(diào)用,則可以為客戶端計算機釋放占用的線程;如果服務(wù)器端支持異步 Web 服務(wù)調(diào)用,則可以釋放服務(wù)器計算機上占用的線程。但這里有兩個關(guān)鍵的區(qū)別。首先,不是由服務(wù)器代碼調(diào)用 BeginXXX 和 EndXXX 函數(shù),而是由 ASMX 處理程序調(diào)用。其次,您要為 BeginXXX 和 EndXXX 函數(shù)編寫代碼,而不能使用由 WSDL.EXE 或 Visual Studio .NET 中的 Add Web Reference(添加 Web 引用)向?qū)傻拇a。但結(jié)果是相同的,即釋放線程以使其能夠執(zhí)行其他進(jìn)程。

ASMX 處理程序調(diào)用服務(wù)器的 BeginXXX 函數(shù)后,會將線程返回到進(jìn)程線程池,使之能夠處理接收到的任何其他請求。但是,還不能釋放請求的 HttpContext。ASMX 處理程序?qū)⒌却,直到它傳遞給 BeginXXX 函數(shù)的回調(diào)函數(shù)被調(diào)用,它才結(jié)束處理請求。

一旦回調(diào)函數(shù)被調(diào)用,ASMX 處理程序?qū)⒄{(diào)用 EndXXX 函數(shù),使您的 Web 方法可以完成任何所要執(zhí)行的處理,并且可以得到被序列化到 SOAP 響應(yīng)中的返回數(shù)據(jù)。EndXXX 函數(shù)返回后將發(fā)送響應(yīng),只有此時該請求的 HttpContext 才得到釋放。