第17章 控制器可扩展性

----------------------------------------------

提示:.net 4.0 使用 async 和 await 时:Nuget中 加载 Microsoft.Bcl.Async !

----------------------------------------------

一、控制器工厂(IControllerFactory)

  1.作用负责创建对请求进行服务的控制器实例

  2.方法:(1)CreateController(RequestContext requestContext,string controllerName)

      --MVC框架需要控制器对请求进行服务时调用。创建能够对当前请求进行处理的实例。

      (2)SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext,string controllerName)

      --指定处理请求所需的会话支持的类型。是否应该为控制器维护会话数据。

      (3)ReleaseController(IController controller) --资源释放。

RequestContext属性

名称 类型 描述
HttpContext HttpContextBase HTTP请求的信息
RouteData RouteData 与请求匹配的路由信息

  3.默认控制器工厂(DefaultControllerFactory)

    (1)与路由中controller匹配的类的要求:

    public类

     具体类(不是抽象类)

    没有泛型(Generic)参数

    以Controller结尾

    实现IController接口

    (2)创建自定义控制器工厂:对默认工厂的设置进行配置,或重写它的一些方法。

     (3)命名空间优先:Global优先级会被路由优先级所重写。:用户可以定义一个全局策略,然后在必要时定制个别路由。               

 //全局策略:命名空间Myprojdet下的所有子空间优先相对与其它命名空间,本身没有优先顺序,是一视同仁的
          ControllerBuilder.Current.DefaultNamespaces.Add("Myprojdet.*");

     (4)定制控制器实例化:1.使用依赖性解析器;2.使用控制器激活器

     (5)重写DefaultControllerfactory方法

可重写的DefaultControllerfactory方法

方法 结果 描述
CreateController IController IControllerFactory接口的CreateController方法的实现。默认这个方法调用GetControllerType来确认控制器实例化的类型,将结果传递给GetControllerInstance方法来获得一个控制器对象。
GetControllerType Type 将请求映射到控制器类型。
GetControllerInstance IController 创建指定类型的实例。

二、动作调用器(IActionInvoker)负责查找并调用控制器类中的动作方法

1.动作调用器是包含在Controller类中的一部分功能。

  2.当控制器通过Controller类派生而来时,动作是由动作调用器(IActionInvoker)来调用,当直接通过IController接口创建控制器时,则要自己去负责执行动作。

  3.bool InvokeAction(ControllerContext controllerContext,string actionName)

 true表示找到并调用了这个动作;false表示控制器没有匹配的动作(返回401-未找到)。

  注:动作是一种行为,而动作方法是实现这种行为的代码。动作调用器的作用:实现对一个动作的调用,而控制器中才是实现这个动作的动作方法。

  4.Controller.ActionInvoker属性获得或设置控制器相关联的动作调用器。(不建议使用)

  5.内建动作调用器(ControllerActionInvoker):依靠(动作)方法进行操作。 方法条件:

    该方法必须是public

    不是Static(静态方法)

    必须不在System.Web.Mvc.Controller、或它的任何基类中。(不能与所有父类方法重复,如:ToString、GetHashCode)

    没有专用名(构造器、属性、事件访问器)。

不是泛型方法(抛异常)

  6.使用自定义方法名:

    使用注解属性[ActionName("Enumerate")]    

 [ActionName("Enumerate")]
        public ViewResult List()
        {

            return View("Result", new Result()
            {
                ControllerName = "Customer",
                ActionName = "List"
            });
        }

    重写原因:

      1.可以接收一个C#方法名不合法的动作名([ActionName("List-Enumerate")])

        2. 如果希望有两个不同的C#方法接收同一组参数,并且运用同样的动作名,但却要对不同的HTTP请求类型进行响应。

  7.使用动作方法选择:派生于ActionMethodSelectorAttribute类

    [HttpPost] [HttpGet] [HttpPut]  .....[NonAction](404-NotFound)

      调用器会优先考虑具有选择器的动作。

    动作方法的去歧义过程:

        首先,调用器会根据名称尽可能的丢弃掉一些方法(名称不相同)。

        其次,调用器丢弃选择器注解属性返回false的动作方法。

      此时,得到一个方法就调用,多个方法就抛异常。没有找到继续:

        再次,查找不带注解属性的方法。

      此时,得到一个方法就调用,多个方法就抛异常。

    处理未知动作:

      InvokeAction返回false,调用HandleUnknownAction方法,返回“404-未找到”。可以重写此方法:      

 protected override void HandleUnknownAction(string actionName)
        {
            Response.Write(string.Format("你请求的{0}方法不存在!" ,actionName));
        }

三、特殊控制器:提高应用程序的请求处理能力!!!!!

    ViewBag特性是不受会话状态影响的。

  1.使用无会话控制器(DefaltControllerFactory):用于处理一个请求时,MVC框架不加载或不存储会话的状态;重叠请求可以同时处理。

SessionStateBehavior枚举值

描述 HttpContext.Session值
Default 使用默认的ASP.NET行为,根据HttpContext来决定会话状态的配置 /
Required 启用完全的读写会话状态 /
ReadOnly 启用只读会话状态 Session["name"]修改会抛异常
Disabled 完全禁用会话状态 null,Session["name"]读取、修改都会抛异常

  DefaltControllerFactory管理会话状态:将SessionState注解属性运用于每一个控制器类(不能用于Action方法)。

 [SessionState(SessionStateBehavior.Disabled)]
    public class ProductController : Controller
    {
       。。。。。。
    }

  2.异步控制器:

    工作线程:工作线程池中的一个工作线程。

    工作线程池:用来处理客户请求的.net线程池。

    当收到一个请求时,将占用一个工作线程,以进行对请求进行处理,当处理完成后,该线程被返回线程池(不回收)等待处理下一个请求。

    使用线程池的好处:

      1.通过重用工作线程,避免每次处理请求时,创建新线程的开销。

      2.通过具有固定数目的可用工作线程,避免了超出服务器处理能力的并发请求情况。

    当出现依赖于其他服务器、且占用较长时间才能完成的请求时,就会出现线程被占用,处于等待状态,使用应用程序处理停顿,

  而服务器又大片闲置的状态,此时可以使用异步控制器

    异步控制器只能对占用I/O或占用网络带宽,而且非CPU密集型的动作是有用的。解决的问题应当是线程池与

  所处理的请求类型之间搭配不当的情况。线程池意在确保每一个请求得到一片服务器资源,但很可能最终停滞于一组无所事事的工作线程上。

  如果对CPU密集弄动作使用额外的后台线程,那么会因为涉及太多的并发请求而削弱服务器资源。

    System.Web.Mvc.AsyncController对控制器派生,创建一个新的Task对象并await它的响应。

    使用异步控制器的作用:在等待异步方法调用结束期间,不会绑定工作线程,减少服务器的压力。

public async Task<ActionResult> AsyncMethod()
        {
            //调用 RemoteService对象的异步方法
            string data = await new RemoteService().GetStringAsync();
            return View("Data", (object) data);
        } 

        public async Task<ActionResult> DataAsync()
        {
            //调用 RemoteService对象的同步方法
            string data = await Task<string>.Factory.StartNew(
                () => new RemoteService().GetRemoteData());
            return View((object) data);
        } 

     

   

时间: 2024-08-09 16:31:31

第17章 控制器可扩展性的相关文章

第17章 CSS边框与背景(上)

第 17章 CSS边框和背景[上]学习要点:1.声明边框2.边框样式3.圆角边框 本章主要探讨 HTML5中 CSS边框和背景,通过边框和背景的样式设置,给元素增加更丰富的外观.一.声明边框边框的声明有三个属性设置,样式表如下:属性 值 说明 CSS版本border-width 长度值 设置边框的宽度,可选 1border-style 样式名称 设置边框的样式,必选 1border-color 颜色值 设置边框的颜色,可选 1 这三个属性值,只有 border-style是必须声明,才可以出现边

4.13日第12次作业,16章外包,17章需求,19章组织级与大型项目

29-高项-田哲琦 16章.外包管理 1.外包的形式有哪五种?什么是利益关系?P346-348 答:企业现行采用的主要外包形式如下: 1).活动外包 2).服务外包 3).内包 4).合包 5).利益关系. 利益关系(benfit-based relationship),这是一种长期合作关系,双方先为此关系进行投资,再根据预先拟定的协议分享利益,共同承担风险,同时共享利益. 2.外包管理的目标是什么?要实现这个目标,对外包管理提出哪四个方面的要求?P348 答:软件外包管理总的目标是用强有力的手

CSS3秘笈第三版涵盖HTML5学习笔记13~17章

第13章,构建基于浮动的布局 使用的是float(浮动)属性 注:float:none值将取消所有浮动,通常只用来取消元素中已经应用的浮动. 切记:不需要给正文的div设计宽度,即使设计成固定宽度也不用 用浮动进行布局 LayoutGala网站(http://blog.html.it/layoutgala/)上提供了40种不同的CSS设计,但大多只是基本框架,里面只有<div>标签及其定位用的CSS代码 布局生成器,Cridinator(http://gridinator.com)提供了简单的

《构建之法》13,14,15,16,17章读后感

1.13章说的是软件测试,怎么样去测试是最有效率的? 2.14章说到质量保障,具体的花费是多少? 3.15章说到ZBB,如果一个软件遇到了不可修复的bug,还算是一个稳定的软件么? 4.16章说到创新,有实际例子吗? 5.17章的职业道德指的是什么?

C++ Primer Plus 第17章 输入,输出和文件

第17章 输入.输出和文件 1.当到达输入语句时,他将刷新输出缓冲区中当前所有的输出 2.streambuf类 提供了对缓冲区的各种操作 ios_base类表示流的一般特征 ios类基于ios_base,包含了一个指向streambuf对象的指针 ostream类从ios派生,提供可输出方法 istream类从ios派生,提供可输入方法 iostream类基于ostream和istream,继承了输入和输出方法 3.包含iostream则自动创建了8个流对象 cin 标准输入 wcin 宽字符流

《Cracking the Coding Interview》——第17章:普通题——题目13

2014-04-29 00:15 题目:将二叉搜索树展开成一个双向链表,要求这个链表仍是有序的,而且不能另外分配对象,就地完成. 解法:Leetcode上也有,递归解法. 代码: 1 // 17.13 Flatten a binary search tree into a doubly linked list by inorder traversal order. 2 // Use postorder traversal to do the flattening job. 3 #include

《Cracking the Coding Interview》——第17章:普通题——题目14

2014-04-29 00:20 题目:给定一个长字符串,和一个词典.如果允许你将长串分割成若干个片段,可能会存在某些片段在词典里查不到,有些则查得到.请设计算法进行分词,使得查不到的片段个数最少. 解法:用空间换取时间的动态规划算法,首先用O(n^2)的时间判断每一个片段是否在字典里.这个过程其实可以通过字典树来进行加速,时间上能优化一个阶,不过我没写,偷懒用<unordered_set>代表了字典.之后通过O(n)时间的动态规划,dp[i]表示当前位置的查不到的片段的最少个数.对于懂代码的

《Cracking the Coding Interview》——第17章:普通题——题目12

2014-04-29 00:04 题目:给定一个整数数组,找出所有加起来为指定和的数对. 解法1:可以用哈希表保存数组元素,做到O(n)时间的算法. 代码: 1 // 17.12 Given an array of integers and target value, find all pairs in the array that sum up to the target. 2 // Use hash to achieve O(n) time complexity. Duplicates pa

《Cracking the Coding Interview》——第17章:普通题——题目10

2014-04-28 23:54 题目:XML文件的冗余度很大,主要在于尖括号里的字段名.按照书上给定的方式进行压缩. 解法:这题我居然忘做了,只写了一句话的注解.用python能够相对方便地实现,因为有直接的XML工具可以调用.书上的那种要求应该是符合前序遍历规则. 代码: 1 # 17.10 Parse an XML file, and try to save some space by mapping every item name to an integer index. 2 # Ans