一般情況下我們通常在一個(gè)頁面中,結(jié)合頁面事件處理模型,按順序一步一步的聲明各個(gè)處理過程。這就是所說的同步處理(synchronous),我們可以很方便的定義頁面處理的順序。同步處理雖然很方便,但在耗時(shí)高請(qǐng)求處理的時(shí)候就會(huì)暴露嚴(yán)重的問題,在一個(gè)高并發(fā)的網(wǎng)站生產(chǎn)服務(wù)器上,由于.net處理是基于所謂的threadpool的,而threadpool中的處理線程又是有限的,如果當(dāng)前threadpool中的線程已經(jīng)全部用盡,而后繼又有不斷的大規(guī)模請(qǐng)求的話,服務(wù)器的性能就會(huì)嚴(yán)重的下降,更嚴(yán)重的還會(huì)使服務(wù)器崩潰。所以我們關(guān)心最多的就是怎樣來更好的使用的.net threadpool。讓.net更好的發(fā)揮的性能。
說到這就不得不談.net的異步處理(asynchronous),模型一般為beginxxx,endxxx,beginxxx返回一個(gè)iasycresult對(duì)象,其中包含對(duì)當(dāng)前異步操作的信息,而endxxx用戶接受返回值,輸出參數(shù)。.net從threadpool中分配一個(gè)空閑線程給beginxxx然后立即返回給threadpool,等到異步處理結(jié)束時(shí),.net又從threadpool中分配一個(gè)空閑線程用于處理endxxx方法。這樣就可能有足夠的線程用于處理其它的事情。見于篇幅問題這里我們只談asp.net 2.0的異步處理模型,我們都知道在1.x的時(shí)候要很好的建立頁面的異步處理是比較麻煩的,可能微軟很早就認(rèn)識(shí)到了這一點(diǎn),所以在2.0的版本中引入的新的頁面處理模型,加入了方便的異步處理點(diǎn)(asynchronous point)在prerender事件和prerendercomplete事件之間,在這個(gè)異步點(diǎn),頁面需要等待所有的異步處理都完成,所以可以在頁面呈現(xiàn)之前完成你需要的任何效果,極大簡化了建立異步頁面的方法。
首先你要在建立頁面的@page聲明中加入 async="true",這是必須的。設(shè)置告訴asp.net要選用ihttpasynchandler來處理當(dāng)前的頁面。接下來你需要做的一般是在page_load事件處理中使用異步處理過程,現(xiàn)在有兩種途徑:
第一種就是使用page.addonprerendercompleteasync方法來處理需要異步處理的begin和end方法集.如下:
addonprerendercompleteasync(new begineventhandler(mybeginmethod),new endeventhandler(myendmethod));
通過添加上面的方法后,頁面執(zhí)行通常的生命周期事件直到頁面的prerender事件觸發(fā).然后asp.net調(diào)用先前在addonprerendercompleteasync中的注冊(cè)的begin處理程序。通常在begin處理程序中處理的是一些異步的web服務(wù),io以及sql的處理,這樣就可以極大的緩解.net線程池的壓力。例如:
<%@ page async="true" language="c#" %>
<asp:content id="content" contentplaceholderid="main" runat="server">
<asp:label id="output" runat="server"></asp:label>
</asp:content>
public partial class asyncpage : system.web.ui.page
{
private webrequest m_request;
void page_load (object sender, eventargs e)
{
addonprerendercompleteasync (
new begineventhandler(beginasyncoperation),
new endeventhandler (endasyncoperation)
);
}
iasyncresult beginasyncoperation (object sender, eventargs e, asynccallback cb, object state)
{
m_request = webrequest.create("http://www.dofor.cn");
return m_request.begingetresponse (cb, state);
}
void endasyncoperation (iasyncresult ar)
{
string text;
using (webresponse response = m_request.endgetresponse(ar))
{
using (streamreader reader = new streamreader(response.getresponsestream()))
{
text = reader.readtoend();
}
}
regex regex = new regex ("href//s*=//s*/"([^/"]*)/"", regexoptions.ignorecase);
matchcollection matches = regex.matches(text);
stringbuilder builder = new stringbuilder(1024);
foreach (match match in matches)
{
builder.append (match.groups[1]);
builder.append("<br/>");
}
output.text = builder.tostring ();
}
}
第二中就是注冊(cè)異步任務(wù)(register asynchronous task).registerasynctask比addonprerendercompleteasync具有更大的靈活性和更多的優(yōu)勢(shì)。它可以允許你聲明一個(gè)超時(shí)參數(shù),同樣可以聲明在@page中如:asynctimeout="5",以秒為單位,但要注意的是這里聲明不是每個(gè)異步處理過程的超時(shí)而是整個(gè)頁面的處理時(shí)間超時(shí)。同樣.net framework 2.0還為注冊(cè)任務(wù)引入了新的methodasync,methodasync就是為了方便處理多個(gè)異步過程的。例如:
<%@ page async="true" language="c#" %>
<asp:content id="content" contentplaceholderid="main" runat="server">
<asp:label id="output" runat="server"></asp:label>
</asp:content>
public partial class asyncpagetask : system.web.ui.page
{
private webrequest m_request;
protected void page_load(object sender, eventargs e)
{
pageasynctask task = new pageasynctask(
new begineventhandler(beginasyncoperation),
new endeventhandler(endasyncoperation),
new endeventhandler(timeoutasyncoperation),
null
);
registerasynctask(task);
}
iasyncresult beginasyncoperation(object sender, eventargs e, asynccallback cb, object state)
{
m_request= webrequest.create("http://www.dofor.cn");
return m_request.begingetresponse(cb, state);
}
void endasyncoperation(iasyncresult ar)
{
string text;
using (webresponse response = m_request.endgetresponse(ar))
{
using (streamreader reader = new streamreader(response.getresponsestream()))
{
text = reader.readtoend();
}
}
regex regex = new regex("href//s*=//s*/"([^/"]*)/"", regexoptions.ignorecase);
matchcollection matches = regex.matches(text);
stringbuilder builder = new stringbuilder(1024);
foreach (match match in matches)
{
builder.append(match.groups[1]);
builder.append("<br/>");
}
output.text = builder.tostring();
}
void timeoutasyncoperation(iasyncresult ar)
{
output.text = "當(dāng)前數(shù)據(jù)不可用";
}
}
總之合理的利用asp.net 2.0的異步處理,就可以極大的改善您大吞吐量高并發(fā)網(wǎng)站頁面的性能。最大的網(wǎng)站源碼資源下載站,