zoukankan      html  css  js  c++  java
  • ASP.NET 页面异步任务

    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请求,等待服务器新的响应

  • 相关阅读:
    大型项目生产环境日志查询
    泛型接口和泛型方法
    使用360浏览器登录B站的时候,不显示搜索框
    构建之法第二周学习体验
    构建之法首周阅读体会
    C语言实例解析精粹学习笔记——26
    C语言实例解析精粹学习笔记——29
    C语言实例解析精粹学习笔记——28
    C语言实例解析精粹学习笔记——18
    C语言实例解析精粹学习笔记——30
  • 原文地址:https://www.cnblogs.com/FlyCat/p/2578593.html
Copyright © 2011-2022 走看看