充分发挥异步在 ASP.NET 中的强大优势

作者:Brij Bhushan Mishra

最近几年,异步编程受到极大关注,主要是出于两个关键原因:首先,它有助于提供更好的用户体验,因为不会阻塞 UI 线程,避免了处理结束前出现 UI 界面挂起。其次,它有助于大幅扩展系统,而且无需添加额外硬件。

但是,编写合适的异步代码来管理线程本身是项乏味的工作。虽然如此,其巨大好处让许多新旧技术纷纷开始使用异步编程。微软自发布了 .NET 4.0以后也对其投入颇多,随后在 .NET 4.5中引入了 async 和 await 关键字,使异步编程变得前所未有地简单。

但是,ASP.NET 中的异步功能自一开始就可以使用,只是从来没有得到应有的重视。而且,考虑到 ASP.NET 和 IIS 处理请求的方式,异步体现的优势可能更明显。通过异步,我们很容易就可以大幅提高 ASP.NET 应用程序的扩展性。随着新的编程结构引入,如 async 和 await 关键字,我们也应该学会使用异步编程的强大功能。

在本篇博文中,我们将讨论一下 IIS 和 ASP.NET 处理请求的方式,然后看看 ASP.NET 中哪些地方可以使用异步,最后再讨论几个最能体现异步优势的场景。

请求是如何处理的?

每个 ASP.NET 请求都要先通过 IIS,然后再由 ASP.NET 处理程序进行最终处理。 首先IIS 接收请求,初步处理后,发送给ASP.NET(必须是一个ASP.NET请求),然后由ASP.NET进行实际处理并生成响应,之后该响应通过IIS发回给客户。在IIS上,有一些工作进程负责从队列中取出请求,并执行IIS 模块,然后再将该请求发送到ASP.NET 队列。但是,ASP.NET本身不创建任何线程,也没有处理请求的线程池,而是通过使用CLR 线程池,从中获取线程来处理请求。因此,IIS 模块调用ThreadPool.QueueUserWorkItem,将请求排入队列,供CLR 工作线程处理。我们都知道,CLR线程池是由CLR管理,并且能够自动调整(也就是说,它根据需要创建和销毁进程)。这里还要记住,创建和销毁线程是项很繁重的任务,这就是为什么CLR线程池允许使用同一个线程处理多个任务。下面来看一个描述请求处理过程的图示。

在上图中可以看到,请求首先由 HTTP.sys接收,并添加到相应内核级应用程序池队列。然后,一个IIS工作线程从队列中取出请求,处理后将其传到ASP.NET 队列。注意,该请求如果不是一个ASP.NET请求,将从 IIS 自动返回。最后,从CLR线程池中分配一个线程,负责处理该请求。

ASP.NET中异步的使用场景是?

所有请求大致可以分为两类: 
1. CPU Bound 类 
2. I/O Bound 类

CPU Bound 类请求,需要 CPU 时间,而且是在同一进程中执行;而 I/O Bound 类请求,本身具有阻塞性,需要依赖其他模块执行 I/O 操作并返回响应。阻塞性请求是提高应用程序可伸缩性的主要障碍,而且大多数web应用程序中,在等待 I/O 操作的过程中浪费了大量时间。 因此以下场景适合使用异步:

  1. I/O Bound 类请求,包括:

    a. 数据库访问

    b. 读/写文件

    c. Web 服务调用

    d. 访问网络资源

  2. 事件驱动的请求,比如SignalR
  3. 需要从多个数据源获取数据的场景

作为示例,这里创建一个简单的同步页面,然后再将它转换成异步页面。 本示例设置了1000ms的延迟(以模拟一些繁重的数据库或web服务调用等),而且还使用WebClient下载了一个页面,如下所示:

    protected void Page_Load(object sender, EventArgs e)

    {

        System.Threading.Thread.Sleep(1000);

        WebClient client = new WebClient();

        string downloadedContent = client.DownloadString("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx");

        dvcontainer.InnerHtml = downloadedContent;

    }

现在将该页面转换成异步页面,这里主要涉及三个步骤:

  1. 在页面指令中添加Async = true,将该页面转换成异步页面,如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="AsyncTest.Home" Async="true" AsyncTimeout="3000" %>

这里还添加了 AsyncTimeout (可选项),请根据需求选择。

2.将此方法转换成异步方法。在这里把Thread.Sleep 与 client.DownloadString 转换成异步方法如下所示:

    private async Task AsyncWork()

    {

        await Task.Delay(1000);

        WebClient client = new WebClient();

        string downloadedContent = await client.DownloadStringTaskAsync("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx ");

        dvcontainer.InnerHtml = downloadedContent;

    }

3.现在可以直接在 Page_Load (页面加载)上调用此方法,使其异步,如下所示:

    protected async void Page_Load(object sender, EventArgs e)

    {
        await AsyncWork();
    }

但是这里的 Page_Load 返回的类型是async void,这种情况无论如何都应该避免。我们知道,Page_Load 是整个页面生命周期的一部分,如果我们把它设置成异步,可能会出现一些异常情况和事件,比如生命周期已经执行完毕而页面加载仍在运行。 因此,强烈建议大家使用 RegisterAsyncTask 方法注册异步任务,这些异步任务会在生命周期的恰当时间执行,可以避免出现任何问题。

    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(AsyncWork));
    }

现在,页面已经转换成了异步页,它就不再是一个阻塞性请求。

笔者在 IIS8.5 上部署了同步页面和异步页面,并使用突发负载对两者进行了测试。测试结果发现,相同的机器配置,同步页面在2-3秒内只能提取1000个请求,而异步页面能够为2200多个请求提供服务。此后,开始收到超时(Timeout)或服务器不可用(Server Not Available)的错误。虽然两者的平均请求处理时间没有多大差别,但是通过异步页面,可以处理两倍以上的请求。这足以证明异步编程功能强大,所以应该充分利用它的优势。

ASP.NET中还有几个地方也可以引入异步:

  1. 编写异步模块
  2. 使用IHttpAsyncHandler 或 HttpTaskAsyncHandler 编写异步HTTP处理程序
  3. 使用web sockets 或 SignalR

结论

本篇博文中,我们讨论了异步编程,而且发现,新推出的async 和 await关键字,使异步编程变得十分简单。我们讨论的话题包括 IIS和ASP.NET如何处理请求,以及在哪些场景中异步的作用最明显。另外,我们还创建了一个简单示例,讨论了异步页面的优势。最后我们还补充了几个ASP.NET中可以使用异步的地方。

本文系 OneAPM 工程师编译呈现。OneAPM 能助您轻松锁定 .NET 应用性能瓶颈,通过强大的 Trace 记录逐层分析,直至锁定行级问题代码。以用户角度展示系统响应速度,以地域和浏览器维度统计用户使用情况。想阅读更多技术文章,请访问OneAPM 官方博客

原文地址:http://www.infragistics.com/community/blogs/brijmishra/archive/2015/10/28/leveraging-the-power-of-asynchrony-in-asp-net.aspx

本文转自 OneAPM 官方博客

时间: 2024-08-05 06:37:55

充分发挥异步在 ASP.NET 中的强大优势的相关文章

看stackoverflow大牛如何回答何时在ASP.NET中使用异步控制器?

转载自博客园:http://farb.cnblogs.com/ 今天无意中看到stackoverflow上一个很好的问答,个人觉得很有价值,所以翻译过来和大家共享!希望大家能相互交流. 在ASP.NET MVC中何时使用异步控制器(Async Controllers)? 在ASP.NET MVC中使用异步操作的时候,我有这么几个关注点.异步操作何时提高我应用的性能,什么时候没改善? 在ASP.NET MVC中到处使用异步操作真的好吗? 对于可等待的(awaitable)方法: 当查询数据库时(通

asp.net中javascript与后台c#交互

asp.net中javascript与后台c#交互 作者:熊猫大叔 字体:[增加 减小] 类型:转载 时间:2015-10-23我要评论,出处:http://www.jb51.net/article/73793.htm 这篇文章主要介绍了asp.net中javascript与后台c#交互,需要的朋友可以参考下 最近做一个小项目,网页中嵌入google maps,输入经纬度坐标可以定位地图位置并加注标记,点击标记获取远端摄像头数据并在视频窗口实现播放.在实际操作过程中,由于经纬度数据和视频登录的用

ASP.NET中进行消息处理(MSMQ) 二

在我上一篇文章<ASP.NET中进行消息处理(MSMQ)一>里对MSMQ做了个通俗的介绍,最后以发送普通文本消息和复杂的对象消息为例介绍了消息队列的使用. 本文在此基础上继续介绍MSMQ的相关知识点,最后还是通过一个示例程序来分析MSMQ在实际项目开发中的应用. 建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:<ASP.NET中进行消息处理(MSMQ)一>. 一.消息传递的优先级      在MSMQ中消息在队列里传输是分有优先级的,这里我就以实例的形式介绍下关于优

ASP.NET中进行消息处理(MSMQ) 三

在本文的前两篇文章里对MSMQ的相关知识点进行了介绍,很多阅读过这前两篇文章的朋友都曾问到过这样一些问题:  1.如何把MSMQ应用到实际的项目中去呢?  2.可不可以介绍一个实际的应用实例?  3....... 在前两篇文章里,关于MSMQ常用的技术点基本介绍完毕了,本文主要以MS开源项目PetShop中的MSMQ应用作为案例来介绍MSMQ在实际项目中的应用.在PetShop里,由于系统使用了多线程的专用应用程序来监控消息队列,在进入PetShop应用分析前,我们先来了解下关于多线程和MSMQ

asp.net中利用JSON进行增删改查中运用到的方法

//asp.net中 利用JSON进行操作, //增加: //当点击"增加链接的时候",弹出增加信息窗口,然后,在窗体中输入完整信息,点击提交按钮. //这里我们需要考虑这些:我会进行异步提交,使用jquery中的方法,$.post("网页名",JSON,callback); //JSON的写法:{"name":name,"id":id},那我们对其进行假设,比方说,表单中的textbox很多,需要我们填写的信息 //也很多,

ASP.NET中进行消息处理(MSMQ) 三(转)

在本文的前两篇文章里对MSMQ的相关知识点进行了介绍,很多阅读过这前两篇文章的朋友都曾问到过这样一些问题:  1.如何把MSMQ应用到实际的项目中去呢?  2.可不可以介绍一个实际的应用实例?  3....... 在前两篇文章里,关于MSMQ常用的技术点基本介绍完毕了,本文主要以MS开源项目PetShop中的MSMQ应用作为案例来介绍MSMQ在实际项目中的应用.在PetShop里,由于系统使用了多线程的专用应用程序来监控消息队列,在进入PetShop应用分析前,我们先来了解下关于多线程和MSMQ

ASP.NET中进行消息处理(MSMQ) 二(转)

在我上一篇文章<ASP.NET中进行消息处理(MSMQ)一>里对MSMQ做了个通俗的介绍,最后以发送普通文本消息和复杂的对象消息为例介绍了消息队列的使用. 本文在此基础上继续介绍MSMQ的相关知识点,最后还是通过一个示例程序来分析MSMQ在实际项目开发中的应用. 建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:<ASP.NET中进行消息处理(MSMQ)一>. 一.消息传递的优先级      在MSMQ中消息在队列里传输是分有优先级的,这里我就以实例的形式介绍下关于优

comet在asp.net中的实现

网上有关"服务器推送"的介绍非常多,其中一种实现方式就是采用comet技术,在浏览器与服务端之间建立一个http协议的"长连接",所谓"长连接",就是指浏览器到服务端的http请求不会马上得到服务端的应答,而是当满足一定条件的时候,服务器端才"主动"将数据返回给浏览器,这时候一次http请求才完成,普通http连接与http长连接见下图: 图1 如上图,左边为一般http连接,服务端收到浏览器的http请求后会立即做出应答,右

asp.net中缓存的使用介绍一

asp.net中缓存的使用介绍一 介绍: 在我解释cache管理机制时,首先让我阐明下一个观念:IE下面的数据管理.每个人都会用不同的方法去解决如何在IE在管理数据.有的会提到用状态管理,有的提到的cache管理,这里我比较喜欢cache管理,因为本人比较喜“cache”这个词.但是状态管理和cache管理这两个在概念和意义上是不同的,下面就让我们来讨论下两都在各个方面的不同之处. 虽然cache管理并不存在于Windows程序,但在web环境中已经得到巨大的应用.自从HTTP变成无协议以来,在