1、同步和非同步區別
當未使用非同步頁時,一個線程只能為同一個頁面的請求服務. 即使頁面請求過程中處理其它的I/O等操作時,此線程也一直處於等待狀態. 當此頁面使用完此線程時,才將它放回到線程池. 線程數量是有限的! 所以當不使用線程時及時放回線池可以使系統效能大大提高!
當使用了非同步頁功能時,如右圖中,開始Thread1是為頁面服務的,但當頁面處理其它的事情(比如I/O或調用其它WebService) 時,Thread1被放回線程池, 此時Thread1可以為其它頁面請求服務了. 當此頁面執行完自己的操作回來後, Thread2接著為頁面請求服務,並不是使用的原來的線程Thread1. 這樣網站的伸縮性會更好.
2、使用樣本
public partial class _Default : System.Web.UI.Page{ const string RSSFEED = "http://weblogs.asp.net/scottgu/rss.aspx"; private WebRequest req; public string rssResult; public int tick; protected void Page_Load(object sender, EventArgs e) { int started = System.Environment.TickCount; AddOnPreRenderCompleteAsync( new BeginEventHandler(BeginTask), new EndEventHandler(EndTask)); tick = System.Environment.TickCount - started; //PageAsyncTask task = new PageAsyncTask( // new BeginEventHandler(BeginTask), // new EndEventHandler(EndTask), // new EndEventHandler(TimeOut), // null); //RegisterAsyncTask(task); } IAsyncResult BeginTask(object sender, EventArgs e, AsyncCallback cb, object state) { Trace.Warn("Begin asyc: Thread=" + Thread.CurrentThread.ManagedThreadId.ToString()); req = WebRequest.Create(RSSFEED); return req.BeginGetResponse(cb, state); } void EndTask(IAsyncResult ar) { using (WebResponse response = req.EndGetResponse(ar)) { StreamReader reader; using (reader = new StreamReader(response.GetResponseStream())) { rssResult = reader.ReadToEnd(); } } Trace.Warn("End async: Thread=" + Thread.CurrentThread.ManagedThreadId.ToString()); } void TimeOut(IAsyncResult ar) { Response.Write("Time Out"); Response.End(); } }
前台頁面