• 让WebForm异步起来


    首先需要明白的是同步和异步的区别,撇开生硬的定义不谈,就以线程IO请求来说,同步就是让一个线程A去进行IO请求,当请求没有完成之前,线程A一直不离不弃的在那里死等,直到得到请求,可以想象,如果运用同步到请求队列中,这将是一个耗时费力的工作。但是如果采用异步请求的时候,当线程A去进行IO请求的时候,没有得到请求结果之前,线程A可以去做别的事情。这样,利用这种方式,可以提高服务器的吞吐量,MSDN中对此解释如下:

    异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库。异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时,应用程序可在异步方法执行其任务时继续执行。

    那么在WebForm编程模型中,怎么实现异步呢?

    首先来看看Asp.net生命周期和异步生命周期的对比(图片来源网络,如有侵权,请告知):

    其实很简单,只要在页面首部写上Async="true" 的标记即可让这个页面异步起来。

    至于在页面中实现异步,这里有两个方法:AddOnPreRenderCompleteAsyncRegisterAsyncTask

    首先,对于AddOnPreRenderCompleteAsync方法,代码如下:

    using System;
    using System.IO;

    namespace AsyncPagesApp
    {
    public partial class _Default : System.Web.UI.Page
    {
    FileStream fileStream; //文件流

    protected void Page_Load(object sender, EventArgs e)
    {
    if (IsPostBack) return;

    fileStream = new FileStream(@"\\***\20111122_EXO.txt",FileMode.Open); //文件流位置
    AddOnPreRenderCompleteAsync(BeginAsyncOperation,EndAsyncOperation); //注册异步事件
    }

    private IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state) //开始异步
    {
    int bufferSize = 99999999;
    byte[] buffer = new byte[bufferSize];

    return fileStream.BeginRead(buffer,0,bufferSize,cb,state);
    }

    private void EndAsyncOperation(IAsyncResult ar) //异步结束
    {
    int fileReadByte = (int)fileStream.EndRead(ar); //得到异步执行结果
    fileStream.Flush();
    fileStream.Close(); //关闭流
    Label1.Text = fileReadByte.ToString();
    }
    }
    }

    对于RegisterAsyncTask方法,代码如下:

    using System;
    using System.Web.UI;
    using System.IO;

    namespace AsyncPagesApp
    {
    public partial class RegisterAsyncTaskPage : System.Web.UI.Page
    {
    FileStream fileStream;

    protected void Page_Load(object sender, EventArgs e)
    {
    if (IsPostBack) return;

    //准备文件流读取
    fileStream = new FileStream(@\\***\20111122_EXO.txt, FileMode.Open);

    //申明异步任务
    PageAsyncTask task = new PageAsyncTask(BeginAsync,EndAsync,TimeoutAsync,true);
    //注册异步任务
    RegisterAsyncTask(task);
    //开始运行
    ExecuteRegisteredAsyncTasks();
    }

    //开始运行
    protected IAsyncResult BeginAsync(object sender, EventArgs e, AsyncCallback cb, object state)
    {
    int bufferSize = 99999999;
    byte[] buffer = new byte[bufferSize];


    return fileStream.BeginRead(buffer, 0, bufferSize, cb, state);
    }

    //运行结束
    protected void EndAsync(IAsyncResult ar)
    {
    int fileReadByte = (int)fileStream.EndRead(ar); //运行结束
    fileStream.Flush();
    fileStream.Close();//关闭
    Label1.Text = fileReadByte.ToString();
    }

    protected void TimeoutAsync(IAsyncResult ar)
    {
    Label1.Text = "server Invalid! ";
    fileStream.Close();
    }
    }
    }

    从上面的代码,可以发现这两种异步方式的区别,第一种方式提供了一种比较简便的编程模型,只需要Begin***和End***方法即可,但是第一种方式不支持超时方式,并且,在第一种异步方式编程的内部,某些变量的值是不能获取的,比如说User.Identity.Name,但是在第二种异步方法中,是可以获取到的。同时需要说明的是在第二种异步方法中,最后一个参数如果设置为True的话,可以让多个任务并行运行。

  • 相关阅读:
    【emWin】例程二十:窗口对象——Dropdown
    【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-11层驱动之FSMC
    【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-10底层驱动之I2C
    【emWin】例程十九:窗口对象——Checkbox
    【iCore3应用】基于iCore3双核心板的编码器应用实例
    【emWin】例程十八:jpeg图片显示
    【GMT43液晶显示模块】发布原理图、出厂代码
    【iCore3应用开发平台】发布 iCore3 应用开发平台出厂代码rev0.0.6
    【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-9底层驱动之USART
    【6集iCore3_ADP触摸屏驱动讲解视频】6-6 底层驱动之触摸操作
  • 原文地址:https://www.cnblogs.com/scy251147/p/2263628.html
Copyright © 2020-2023  润新知