zoukankan      html  css  js  c++  java
  • 第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);
            } 

     

         

       

  • 相关阅读:
    《测试工作量的时间评估》方案梳理
    GitHub 生成密钥
    Jenkins+Jmeter持续集成(五、Ant+GitLab持续构建)
    Linux下查看文件和文件夹大小
    Java Runtime.exec()的使用
    如何启动/停止/重启MySQL
    浅析Java语言慢的原因
    chattr命令锁定账户敏感文件
    SOAP协议初级指南 (三)
    SOAP协议初级指南 (二)
  • 原文地址:https://www.cnblogs.com/wjs5943283/p/4652496.html
Copyright © 2011-2022 走看看