服務(wù)器端異步 Web 方法(一)
發(fā)表時間:2024-06-16 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]摘要: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 才得到釋放。