服務(wù)器端異步 Web 方法(一)
發(fā)表時(shí)間:2024-02-17 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]摘要:Matt Powell 介紹了如何在服務(wù)器端使用異步 Web 方法,來(lái)創(chuàng)建高性能的 Microsoft ASP.NET Web 服務(wù)。 簡(jiǎn)介在九月份的第三篇專(zhuān)欄(英文)中,我談到了利用 Microsoft® .NET Framework 的客戶(hù)端功能通過(guò) HTTP 異步調(diào)用 ...
摘要:Matt Powell 介紹了如何在服務(wù)器端使用異步 Web 方法,來(lái)創(chuàng)建高性能的 Microsoft ASP.NET Web 服務(wù)。
簡(jiǎn)介
在九月份的第三篇專(zhuān)欄(英文)中,我談到了利用 Microsoft® .NET Framework 的客戶(hù)端功能通過(guò) HTTP 異步調(diào)用 Web 服務(wù)的問(wèn)題。這種調(diào)用 Web 服務(wù)的方法非常有用,使用時(shí)不必鎖定您的應(yīng)用程序或產(chǎn)生過(guò)多后臺(tái)線(xiàn)程,F(xiàn)在我們了解一下在服務(wù)器端提供類(lèi)似功能的異步 Web 方法。異步 Web 方法在編寫(xiě) ISAPI 擴(kuò)展方面具有與 HSE_STATUS_PENDING 方法類(lèi)似的高性能,但不需要為管理自己的線(xiàn)程池編寫(xiě)代碼,同時(shí)又具有以托管代碼方式運(yùn)行的所有優(yōu)點(diǎn)。
首先我們考慮一下常規(guī)的同步 Microsoft® ASP.NET Web 方法。當(dāng)您從同步 Web 方法返回時(shí),將發(fā)送對(duì)該方法的響應(yīng)。如果需要較長(zhǎng)的時(shí)間來(lái)完成請(qǐng)求,則處理請(qǐng)求的線(xiàn)程會(huì)一直被占用,直到方法調(diào)用結(jié)束。不幸的是,多數(shù)較長(zhǎng)的調(diào)用是由較長(zhǎng)的數(shù)據(jù)庫(kù)查詢(xún)或?qū)α硪粋(gè) Web 服務(wù)的調(diào)用等事件引起的。例如,如果您調(diào)用數(shù)據(jù)庫(kù),當(dāng)前線(xiàn)程會(huì)一直等待調(diào)用完成。線(xiàn)程無(wú)事可做,只是等待,直至聽(tīng)到查詢(xún)的返回。當(dāng)線(xiàn)程等待完成對(duì) TCP 套接字或后端 Web 服務(wù)的調(diào)用時(shí),也會(huì)出現(xiàn)類(lèi)似的問(wèn)題。
讓線(xiàn)程處于等待狀態(tài)很不好,特別是在服務(wù)器的運(yùn)行壓力很大的情況下。等待中的線(xiàn)程不會(huì)進(jìn)行任何有效工作,例如為其他請(qǐng)求提供服務(wù)。我們需要找到一種方法,能夠在服務(wù)器上開(kāi)始較長(zhǎng)的后臺(tái)進(jìn)程,同時(shí)又能將當(dāng)前線(xiàn)程返回到 ASP.NET 進(jìn)程池。然后,當(dāng)較長(zhǎng)的后臺(tái)進(jìn)程完成時(shí),我們調(diào)用一個(gè)回調(diào)函數(shù),結(jié)束對(duì)請(qǐng)求的處理,并通過(guò)某種方式通知 ASP.NET 請(qǐng)求已完成。實(shí)際上,這種功能可由 ASP.NET 使用異步 Web 方法提供。
異步 Web 方法的工作原理
當(dāng)您使用 Web 方法編寫(xiě)典型的 ASP.NET Web 服務(wù)時(shí),Microsoft® Visual Studio® .Net 只是編譯您的代碼以創(chuàng)建程序集;當(dāng)收到對(duì)其 Web 方法的請(qǐng)求時(shí),將調(diào)用該程序集。程序集本身并不知道關(guān)于 SOAP 的任何事情。因此,當(dāng)您的應(yīng)用程序首次啟動(dòng)時(shí),ASMX 處理程序必須反映您的程序集,以確定提供哪些 Web 方法。對(duì)于常規(guī)的同步請(qǐng)求,這些操作都很簡(jiǎn)單:找出哪些方法具有關(guān)聯(lián)的 WebMethod 屬性、基于 SOAPAction HTTP 標(biāo)頭來(lái)設(shè)置調(diào)用正確方法的邏輯。
對(duì)于異步請(qǐng)求,在反映過(guò)程中,ASMX 處理程序?qū)ふ揖哂心撤N簽名并將簽名識(shí)別為異步的 Web 方法。該處理程序?qū)ふ曳弦韵乱?guī)則的方法對(duì):
BeginXXX 和 EndXXX Web 方法,其中 XXX 是任意字符串,表示要提供的方法的名稱(chēng)。
BeginXXX 函數(shù)返回一個(gè) IAsyncResult 接口,并分別接受 AsyncCallback 和一個(gè)對(duì)象,作為其最后兩個(gè)輸入?yún)?shù)。
EndXXX 函數(shù)接受一個(gè) IAsyncResult 接口,作為其唯一的參數(shù)。
兩個(gè)方法都必須使用 WebMethod 屬性進(jìn)行標(biāo)識(shí)。
如果 ASMX 處理程序發(fā)現(xiàn)兩個(gè)方法符合上述所有條件,則將方法 XXX 作為常規(guī)的 Web 方法在其 WSDL 中提供。該方法將接受在 BeginXXX 的簽名中的 AsyncCallback 參數(shù)之前定義的參數(shù)作為輸入,并返回由 EndXXX 函數(shù)返回的內(nèi)容。因此,如果某個(gè) Web 方法具有如下同步聲明:
[WebMethod]
public string LengthyProcedure(int milliseconds) {...}
則異步聲明將為:
[WebMethod]
public IAsyncResult BeginLengthyProcedure(
int milliseconds,
AsyncCallback cb,
object s) {...}
[WebMethod]
public string EndLengthyProcedure(IAsyncResult call) {...}
每個(gè)方法的 WSDL 都是相同的。
在 ASMX 處理程序反映程序集并檢測(cè)到某個(gè)異步 Web 方法后,它必須以不同于處理同步請(qǐng)求的方式處理對(duì)該方法的請(qǐng)求。它將調(diào)用 BeginXXX 方法,而不是某個(gè)簡(jiǎn)單方法。它將傳入的請(qǐng)求還原序列化到要傳遞到函數(shù)的參數(shù)中(與處理同步請(qǐng)求時(shí)一樣);但是它還將指針傳遞到一個(gè)內(nèi)部回調(diào)函數(shù)(作為 BeginXXX 方法的額外 AsyncCallback 參數(shù))。
這種方法類(lèi)似于 .NET Framework 中 Web 服務(wù)客戶(hù)端應(yīng)用程序的異步編程模式。如果客戶(hù)端支持異步 Web 服務(wù)調(diào)用,則可以為客戶(hù)端計(jì)算機(jī)釋放占用的線(xiàn)程;如果服務(wù)器端支持異步 Web 服務(wù)調(diào)用,則可以釋放服務(wù)器計(jì)算機(jī)上占用的線(xiàn)程。但這里有兩個(gè)關(guān)鍵的區(qū)別。首先,不是由服務(wù)器代碼調(diào)用 BeginXXX 和 EndXXX 函數(shù),而是由 ASMX 處理程序調(diào)用。其次,您要為 BeginXXX 和 EndXXX 函數(shù)編寫(xiě)代碼,而不能使用由 WSDL.EXE 或 Visual Studio .NET 中的 Add Web Reference(添加 Web 引用)向?qū)傻拇a。但結(jié)果是相同的,即釋放線(xiàn)程以使其能夠執(zhí)行其他進(jìn)程。
ASMX 處理程序調(diào)用服務(wù)器的 BeginXXX 函數(shù)后,會(huì)將線(xiàn)程返回到進(jìn)程線(xiàn)程池,使之能夠處理接收到的任何其他請(qǐng)求。但是,還不能釋放請(qǐng)求的 HttpContext。ASMX 處理程序?qū)⒌却,直到它傳遞給 BeginXXX 函數(shù)的回調(diào)函數(shù)被調(diào)用,它才結(jié)束處理請(qǐng)求。
一旦回調(diào)函數(shù)被調(diào)用,ASMX 處理程序?qū)⒄{(diào)用 EndXXX 函數(shù),使您的 Web 方法可以完成任何所要執(zhí)行的處理,并且可以得到被序列化到 SOAP 響應(yīng)中的返回?cái)?shù)據(jù)。EndXXX 函數(shù)返回后將發(fā)送響應(yīng),只有此時(shí)該請(qǐng)求的 HttpContext 才得到釋放。