對于前面提到的大多數(shù)異步操作,使用異步 web 方法包裝后端異步調(diào)用很有意義,可以使 web 服務(wù)代碼更有效。但使用委托進(jìn)行異步方法調(diào)用時(shí)除外。委托會(huì)導(dǎo)致異步方法調(diào)用占用進(jìn)程線程池中的某個(gè)線程。不幸的是,asmx 處理程序?yàn)檫M(jìn)入的請求提供服務(wù)時(shí)同樣要使用這些線程。所以與對硬件或網(wǎng)絡(luò)資源執(zhí)行真正 i/o 操作的調(diào)用不同,使用委托的異步方法調(diào)用在執(zhí)行時(shí)仍將占用其中一個(gè)進(jìn)程線程。您也可以占用原來的線程,同步運(yùn)行您的 web 方法。
下面的示例顯示了一個(gè)調(diào)用后端 web 服務(wù)的異步 web 方法。它已經(jīng)使用 webmethod 屬性標(biāo)識了 begingetage 和 endgetage 方法,以便異步運(yùn)行。此異步 web 方法的代碼調(diào)用名為 userinfoquery 的后端 web 方法,以獲得它需要返回的信息。對 userinfoquery 的調(diào)用被異步執(zhí)行,并被傳遞到 asynccallback 函數(shù),后者被傳遞到 begingetage 方法。這將導(dǎo)致當(dāng)后端請求完成時(shí),調(diào)用內(nèi)部回調(diào)函數(shù)。然后,回調(diào)函數(shù)將調(diào)用 endgetage 方法以完成請求。此示例中的代碼比前面示例中的代碼簡單得多,并且還具有另外一個(gè)優(yōu)點(diǎn),即沒有在與為中間層 web 方法請求提供服務(wù)的相同線程池中啟動(dòng)后端處理。
[webservice]
public class getmyinfo : system.web.services.webservice
{
[webmethod]
public iasyncresult begingetage(asynccallback cb, object state)
{
// 調(diào)用異步 web 服務(wù)調(diào)用。
localhost.userinfoquery proxy
= new localhost.userinfoquery();
return proxy.begingetuserinfo("用戶名",
cb,
proxy);
}
[webmethod]
public int endgetage(iasyncresult res)
{
localhost.userinfoquery proxy
= (localhost.userinfoquery)res.asyncstate;
int age = proxy.endgetuserinfo(res).age;
// 在此對 web 服務(wù)的結(jié)果進(jìn)行其他
// 處理。
return age;
}
}
發(fā)生在 web 方法中的最常見的 i/o 操作類型之一是對 sql 數(shù)據(jù)庫的調(diào)用。不幸的是,目前 microsoft® ado.net 尚未定義一個(gè)完好的異步調(diào)用機(jī)制;而只是將 sql 調(diào)用包裝到異步委托調(diào)用中對提高效率沒有什么幫助。雖然有時(shí)可以選擇緩存結(jié)果,但是也應(yīng)當(dāng)考慮使用 microsoft sql server 2000 web services toolkit(英文)將您的數(shù)據(jù)庫發(fā)布為 web 服務(wù)。這樣您就可以利用 .net framework 中的支持,異步調(diào)用 web 服務(wù)以查詢或更新數(shù)據(jù)庫。
通過 web 服務(wù)調(diào)用訪問 sql 時(shí),需要注意眾多的后端資源。如果您使用了 tcp 套接字與 unix 計(jì)算機(jī)通信,或者通過專用的數(shù)據(jù)庫驅(qū)動(dòng)程序訪問其他一些可用的 sql 平臺,甚至具有使用 dcom 訪問的資源,您都可以考慮使用眾多的 web 服務(wù)工具包將這些資源發(fā)布為 web 服務(wù)。
使用這種方法的優(yōu)點(diǎn)之一是您可以利用客戶端 web 服務(wù)結(jié)構(gòu)的優(yōu)勢,例如使用 .net framework 的異步 web 服務(wù)調(diào)用。這樣您將免費(fèi)獲得異步調(diào)用能力,而您的客戶端訪問機(jī)制會(huì)與異步 web 方法高效率地配合工作。
使用異步 web 方法聚合數(shù)據(jù)
現(xiàn)在,許多 web 服務(wù)都訪問后端的多個(gè)資源并為前端的 web 服務(wù)聚合信息。盡管調(diào)用多個(gè)后端資源會(huì)增加異步 web 方法模型的復(fù)雜性,但最終還是能夠顯著提高效率。
假設(shè)您的 web 方法調(diào)用兩個(gè)后端 web 服務(wù):服務(wù) a 和服務(wù) b。從您的 beginxxx 函數(shù),您可以異步調(diào)用服務(wù) a 和服務(wù) b。您應(yīng)該向每個(gè)異步調(diào)用傳遞自己的回調(diào)函數(shù)。在從服務(wù) a 和服務(wù) b 接收到結(jié)果后,為觸發(fā) web 方法的完成,您提供的回調(diào)函數(shù)將驗(yàn)證所有的請求都已完成,在返回的數(shù)據(jù)上進(jìn)行所有的處理,然后調(diào)用傳遞到 beginxxx 函數(shù)的回調(diào)函數(shù)。這將觸發(fā)對 endxxx 函數(shù)的調(diào)用,此函數(shù)的返回將導(dǎo)致異步 web 方法的完成。
小結(jié)
異步 web 方法在 asp.net web 服務(wù)中提供了一個(gè)有效的機(jī)制,可以調(diào)用后端服務(wù),而不會(huì)導(dǎo)致占用卻不利用進(jìn)程線程池中的寶貴線程。通過結(jié)合對后端資源的異步請求,服務(wù)器可以使用自己的 web 方法使同時(shí)處理的請求數(shù)目達(dá)到最大。您應(yīng)該考慮使用此方法開發(fā)高性能的 web 服務(wù)應(yīng)用程序。