实例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
}
{
#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>
<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();
}
}
}
{
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);
}
}
}
{
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返回时根本不用阻塞工作线程。从而使系统有更好的伸缩性和吞吐量。