对于异步的实现,首先进入我们大脑的就是AJAX,AJAX是一种客户端的技术,对于服务端技术的异步微软绝不逊色。。。那么让我们一起来看一下吧。。。
在.NET中,异步都是建立在IAsyncResult接口之上的,而BeginXxxxx/EndXxxxx是对这个接口最直接的使用方式,所以我们来看如下的列子
一、异步 HttpHandler
关于HttpHandler的接口是个同步调用接口,它并没有异步功能。要想支持异步,则必须使用另一个接口:IHttpAsyncHandler
- //定义 HTTP 异步处理程序对象必须实现的协定。
- public interface IHttpAsyncHandler : IHttpHandler
- {
- //启动对 HTTP 处理程序的异步调用。
- //context: 一个 System.Web.HttpContext 对象,该对象提供对用于向 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session
- // 和 Server)的引用。
- //extraData: 处理该请求所需的所有额外数据。
- //cb: 异步方法调用完成时要调用的 System.AsyncCallback。如果 cb 为 null,则不调用委托。
- //返回结果:包含有关进程状态信息的 System.IAsyncResult。
- IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
- // 进程结束时提供异步处理 End 方法。
- // result: 包含有关进程状态信息的 System.IAsyncResult。
- void EndProcessRequest(IAsyncResult result);
- }
这个接口也很简单,只有二个方法,启动对 HTTP 处理程序的异步调用和 进程结束时提供异步处理 End 方法。
下面我们来看一下如何创建一个支持异步的ashx文件
public class AsyncHandler : IHttpAsyncHandler {
- private static readonly string ServiceUrl = "http://localhost:22132/service/DemoService/CheckUserLogin";
- public void ProcessRequest(HttpContext context)
- {
- // 注意:这个方法没有必要实现。因为根本就不调用它。
- // 但要保留它,因为这个方法也是接口的一部分。
- throw new NotImplementedException();
- }
- public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
- {
- // 参数cb是一个ASP.NET的内部委托,EndProcessRequest方法将在那个委托内部被调用。
- LoginInfo info = new LoginInfo();
- info.Username = context.Request.Form["Username"];
- info.Password = context.Request.Form["Password"];
- MyHttpClient<LoginInfo, string> http = new MyHttpClient<LoginInfo, string>();
- http.UserData = context;
- // 注意:您所需要的回调委托,ASP.NET已经为您准备好了,直接用cb就好了。
- return http.BeginSendHttpRequest(ServiceUrl, info, cb, http);
- }
- public void EndProcessRequest(IAsyncResult ar)
- {
- MyHttpClient<LoginInfo, string> http = (MyHttpClient<LoginInfo, string>)ar.AsyncState;
- HttpContext context = (HttpContext)http.UserData;
- context.Response.ContentType = "text/plain";
- context.Response.Write("AsyncHandler Result: ");
- try {
- // 结束异步调用,并取得结果
- string resultdemo = http.EndSendHttpRequest(ar);
- context.Response.Write(resultdemo);
- }
- catch( System.NET.WebException wexb ) {
- context.Response.StatusCode = 500;
- context.Response.Write(HttpWebRequestHelper.SimpleReadWebExceptionText(wexb));
- }
- catch( Exception exb ) {
- context.Response.StatusCode = 500;
- context.Response.Write(exb.Message);
- }
- }
总结如下:
1. 在BeginProcessRequest()方法,调用要你要调用的异步开始方法,通常会是另一个BeginXxxxx方法。
2. 在EndProcessRequest()方法,调用要你要调用的异步结束方法,通常会是另一个EndXxxxx方法。