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