執行個體1 : 在非同步handler中非同步訪問網路 並返回結果
代碼 public class Demo1 : IHttpAsyncHandler
{
#region IHttpAsyncHandler Members
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
context.Response.Write("begin");
var request = (HttpWebRequest)WebRequest.Create("http://www.baidu.com");
return request.BeginGetResponse(ar =>
{
var response = request.EndGetResponse(ar);
byte[] data = new byte[response.ContentLength];
response.GetResponseStream().Read(data, 0, data.Length);
response.Close();
context.Response.Write(Encoding.Default.GetString(data));
cb(ar); //通知asp.net非同步請求已完成
}, context);
}
public void EndProcessRequest(IAsyncResult result)
{
var context = (HttpContext)result.AsyncState; //擷取我們在BeginGetResponse中傳入的HttpContext
context.Response.Write("end");
}
#endregion
#region IHttpHandler Members
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
}
#endregion
}
執行個體2:長串連聊天室default頁面發送訊息。GetMessage非同步handler擷取最新訊息。可以使用ajax輪詢的調用GetMessage.訊息發送時候也可以加入訊息佇列機制和用戶端確認機制。防止訊息丟失!有空在整理吧
default.aspx
代碼 <div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
</div>
default.aspx.cs
代碼 public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
string name = TextBox1.Text.Trim();
string content = TextBox2.Text;
var noticeList = GetMessage.AsyncGetMessageList.Where(ar => ar.UserName == name).ToList();
foreach (var ar in noticeList)
{
GetMessage.AsyncGetMessageList.Remove(ar);
ar.HttpContext.Response.Write(content);
ar.Complete();
}
}
}
GetMessage
代碼namespace AsyncHanlder
{
public class GetMessage : IHttpAsyncHandler
{
public static IList<AsyncGetMessageResult> AsyncGetMessageList = new List<AsyncGetMessageResult>();
public void ProcessRequest(HttpContext context)
{
}
public bool IsReusable
{
get
{
return false;
}
}
#region IHttpAsyncHandler Members
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var ar = new AsyncGetMessageResult(context, cb, extraData);
ar.UserName = "xhan";
AsyncGetMessageList.Add(ar);
return ar;
}
public void EndProcessRequest(IAsyncResult result)
{
//throw new NotImplementedException();
}
#endregion
}
public class AsyncGetMessageResult : IAsyncResult
{
public HttpContext HttpContext { get; set; }
public AsyncCallback AsyncCallback { get; set; }
public string UserName { get; set; }
private object state;
private bool isCompleted;
#region IAsyncResult Members
public object AsyncState
{
get { return state; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { return null; }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return isCompleted; }
}
#endregion
public AsyncGetMessageResult(HttpContext ctx, AsyncCallback cb, object state)
{
this.HttpContext = ctx;
this.AsyncCallback = cb;
this.state = state;
this.isCompleted = false;
}
public void Complete()
{
this.isCompleted = true;
this.AsyncCallback(this);
}
}
}
另外記得不再在非同步作業中調用
ThreadPool.QueueUserWorkItem或者非同步呼叫委託來實現多線程。因為兩者都是使用的線程池中線程來執行方法的,所以這種方式來使用非同步完全是沒有意義的
。應盡量避免對CPU密集操作使用非同步。那到底什麼情況下使用非同步呢?主要是在做IO密集操作時候使用非同步才有意義。這裡指的是採用非同步方式調用io操作。
一般應是調用.net提供的非同步io介面來實現非同步io,比如非同步訪問網路,非同步讀寫檔案(stream.BeiginXXX),非同步訪問資料庫(sqlcommand.beginxxx)等。這些非同步方法呼叫
底層都是通過io完成連接埠來實現非同步io,只需要少數的io線程處理大量io請求。從而在等待io返回時根本不用阻塞背景工作執行緒。從而使系統有更好的伸縮性和輸送量。