在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
PageAsyncTask是任务类,通过 Page.RegisterAsyncTask来注册,Page.ExecuteRegisteredAsyncTasks()调用 页面代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" AsyncTimeout="4" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>Asynchronous Task Example</title> </head> <body> <form id="form1" runat="server"> <div> <span id="TaskMessage" runat=server> </span> </div> </form> </body> </html> 后置代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Threading; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // 定义异步任务. SlowTask slowTask1 = new SlowTask(); SlowTask slowTask2 =new SlowTask(); SlowTask slowTask3 =new SlowTask(); PageAsyncTask asyncTask1 = new PageAsyncTask(slowTask1.OnBegin, slowTask1.OnEnd, slowTask1.OnTimeout, "Async1", true); PageAsyncTask asyncTask2 = new PageAsyncTask(slowTask2.OnBegin, slowTask2.OnEnd, slowTask2.OnTimeout, "Async2", true); PageAsyncTask asyncTask3 = new PageAsyncTask(slowTask3.OnBegin, slowTask3.OnEnd, slowTask3.OnTimeout, "Async3", true); //注册页面异步任务. //单个任务如果超过页面定义的AsyncTimeout,就会调用Timeout委托 Page.RegisterAsyncTask(asyncTask1); Page.RegisterAsyncTask(asyncTask2); Page.RegisterAsyncTask(asyncTask3); DateTime tStart = DateTime.Now; // 执行注册的异步方法,会阻塞线程,直到所有注册方法执行完毕或者超时 Page.ExecuteRegisteredAsyncTasks(); DateTime tEnd = DateTime.Now; TaskMessage.InnerHtml = "Task1:"+slowTask1.GetAsyncTaskProgress() + "<br>" + "Task2:"+slowTask2.GetAsyncTaskProgress() + "<br>" + "Task3:"+slowTask3.GetAsyncTaskProgress() + "<br/>"+ "总开始时间:" + tStart + " 总结束时间:" + tEnd; } public class SlowTask { private static Random rand = new Random(); private String _taskprogress; private AsyncTaskDelegate _dlgt; // Create delegate. protected delegate void AsyncTaskDelegate(); public String GetAsyncTaskProgress() { return _taskprogress; } //实际执行的耗时操作 public void ExecuteAsyncTask() { //随即生产1-5秒模拟调用耗时 int second = rand.Next(1, 5); Thread.Sleep(TimeSpan.FromSeconds(second)); } //异步调用开始时调用 //此方法内一般不放耗时操作,而是内部新建线程执行 public IAsyncResult OnBegin(object sender, EventArgs e, AsyncCallback cb, object extraData) { _taskprogress = "开始时间: " + DateTime.Now + ". "; //这里定义耗时方法的委托,并开始异步执行 //虽然直接将耗时操作直接写在OnBegin可以有相同的效果,但是使用单独委托可以更灵活 //比如可以通过委托传递由外部定义的耗时操作 _dlgt = new AsyncTaskDelegate(ExecuteAsyncTask); IAsyncResult result = _dlgt.BeginInvoke(cb, extraData); return result; } // 异步调用结束时被调用 public void OnEnd(IAsyncResult ar) { _taskprogress += "完成时间: " + DateTime.Now; _dlgt.EndInvoke(ar); } //异步调用在指定时间未完成时被调用(即超时) public void OnTimeout(IAsyncResult ar) { _taskprogress += "异步操作超时"; } } } 用处: 还可以利用ExecuteRegisteredAsyncTasks的阻塞功能实现简单Server-Push效果 思路: 服务端: 可以将异步方法放入某个类实例,方法中使用ManualResetEvent或其他同步类,阻塞方法执行,将类实例放入全局变量中,如Dictionary,当满足某些条件时(如某个请求),在全局变量中找出对应类,通过类的公开方法释放ManualResetEvent锁定返回是数据 客户端:根据服务端返回的信息作出不同反应,不管是超时还是正常得到数据,都再向服务器开ajax请求,等待服务器新的响应 |
请发表评论