• Asp.net MVC 3 异步操作


         在 Asp.net MVC 应用程序中,有时间需要执行一些异步操作。那么 Asp.net MVC 下的异步请求是怎么一个过程呢?  异步被调用时,发生以下过程:

    1. Web服务器从线程池得到一个线程(工作线程),接着安排它来处理进来的请求,该工作线程启动一个异步操作。

    2. 工作线程被线程池收回,为另一个Web请求服务。

    3. 当异步操作完成后,它会通知ASP.NET。

    4. Web服务器从线程池获取一个工作线程(这可能是一个不同的开始异步操作的线程)来处理剩余的请求,包括呈现与响应请求。


    看下面的模式图:

    IC371798Async


    接着,我们来看Controller的代码:

       1:      public class HomeController : AsyncController
       2:      {
       3:          public void IndexAsync()
       4:          {
       5:              AsyncManager.OutstandingOperations.Increment(2);
       6:   
       7:              Task.Factory.StartNew(() =>
       8:                                        {
       9:                                            // Perform some expensive operation
      10:                                            string uri = "http://www.cnblogs.com";
      11:   
      12:                                            WebClient client = new WebClient();
      13:                                            string reply = client.DownloadString(uri);
      14:   
      15:                                            AsyncManager.Parameters["data"] = reply;
      16:                                            AsyncManager.OutstandingOperations.Decrement();
      17:                                        });
      18:              Task.Factory.StartNew(() =>
      19:                                        {
      20:                                            // Perform another expensive operation
      21:                                            string uri = "http://www.cnblogs.com/wintersun/";
      22:   
      23:                                            WebClient client = new WebClient();
      24:                                            string reply = client.DownloadString(uri);
      25:   
      26:                                            AsyncManager.Parameters["moredata"] = reply;
      27:                                            AsyncManager.OutstandingOperations.Decrement();
      28:                                        });
      29:          }
      30:   
      31:          public ActionResult IndexCompleted(string data, string moredata)
      32:          {
      33:              Operations translations = new Operations { FirstOperation = data, SecondOperation = moredata };
      34:   
      35:              return View(translations);
      36:          }
      37:   
      38:      }


    我们看到上面的代码让Controller继承自AsyncController,那个叫IndexAsync的action对应是Index的View。中间的代码使用Task Parallel library(TPL)来模拟下载网页内容,最后在完成后又通过AsyncManager.Parameters字典传值给IndexCompleted的Action, 有注意Key的名称moredata与IndexCompleted Action的参数名moredata相同。AsyncManager下的Parameters字典用于转递一组参数值到最后异步调用的方法。 AsyncManager下有一个管理异步操作的计数器,应当务必确保执行异步操作后,执行Decrement方法,甚至异步操作失败,当所有线程完成时这个计数器的值必须为0。 当异步调用我们让View返回:


       1:  <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<AsyncProject.Models.Operations>" %>
       2:  <!DOCTYPE html>
       3:  <html>
       4:  <head runat="server">
       5:      <title>Translate Completed</title>
       6:  </head>
       7:  <body>
       8:      <div>
       9:          The controller has completed.
      10:      </div>
      11:  </body>
      12:  </html>


    使用到一个简单Model:

        public class Operations
        {
            public string FirstOperation { get; set; }
            public string SecondOperation { get; set; }
        }


    好了,那么什么时候用异步,什么用同步呢?

    当这些条件满足的情况下,可以考虑使用异步:

    1. 密集​​地操作的网络或I/O,而不是CPU密集运算的。
    2. 测试结果表明阻塞操作是网站的性能瓶颈,为了让IIS服务器可以处理更多的请求,在处理这些阻塞调用时使用异步Action方法。
    3. 并行化比简单代码更重要。
    4. 需要提供一种机制,允许用户取消一个长期运行任务的请求。

    实际开发,你需要测试是否异步操作可以提高性能。同时,在某些情况下可能话,增加IIS每个CPU配置最大并发请求处理和最大并发线程。

    关于Asp.net 服务器线程配置看这篇文章:ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0
    关于是否需要数据库异步调用看这里: Should my database calls be Asynchronous

    我们介绍到这儿,有兴趣可以自己尝试一下,后面有时间将介绍Asp.net MVC 4 与 .net framework 4.5 的异步操作。


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    《Linux shell编程中 diff与vimdif的使用》RHEL6
    《mysql数据库备份小脚本》
    《linux下sudo服务的使用》RHEL6
    《通过脚本查看哪些ip被占用》shell笔记
    linux系统环境变量.bash_profile/bashrc文件
    清空系统日志shell scripts——自学笔记
    《linux源代码包的编译安装》RHEL6
    《linux 网卡别名的添加和绑定》RHEL6
    《iptables详解 》RHEL6
    转:swagger 入门
  • 原文地址:https://www.cnblogs.com/wintersun/p/2849710.html
Copyright © 2020-2023  润新知