码迷,mamicode.com
首页 > 其他好文 > 详细

第17章 控制器可扩展性

时间:2015-07-18 22:28:51      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

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

提示:.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);
        } 

 

 

     

   

 

第17章 控制器可扩展性

标签:

原文地址:http://www.cnblogs.com/wjs5943283/p/4652496.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!