成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為ASP.NET MVC擴展異步Action功能(上)

開發 后端
異步請求處理是ASP.NET 2.0中引入的高級特性,它依托IO Complete Port,對于提高IO密集型應用程序的吞吐量非常重要。但是目前ASP.NET MVC框架缺少異步Action功能。本文作者給出了不錯的擴展:完整,方便,并且非常輕巧——核心邏輯代碼只有200行左右,這意味著絕大部分功能將會委托給框架中現成的內容,確保了擴展的穩定,高效并且擁有較好的向后兼容性。

編輯推薦:為ASP.NET MVC擴展異步Action功能(下)

請求處理方式的改變

在制定基本改造策略之前,我們需要了解ASP.NET MVC框架目前的架構及請求處理流程。如下:

◆ 在應用程序啟動時(此時還沒有接受任何請求),將針對MVC請求的Route策略注冊至ASP.NET Routing模塊。此時每個Route策略(即Route對象)中的RouteHandler屬性為ASP.NET MVC框架中的MvcRouteHandler。

◆ 當ASP.NET Routing模塊接收到一個匹配某個Route策略的HTTP請求時,將會調用該Route對象中RouteHandler對象的GetHttpHandler以獲取一個HttpHandler,并交由ASP.NET執行。MvcRouteHandler永遠將返回一個MvcHandler對象。

◆ MvcHandler在執行時,將取出RouteData中的controller值,并以此構建一個實現了IController接口的控制器對象,并調用IController接口的Execute方法執行該控制器。

◆ 對于一個ASP.NET MVC應用程序來說,大部分控制器將會繼承System.Web.Mvc.Controller類型。Controller類將會從RouteData獲取action值,并交給實現IActionInvoker接口的對象來執行一個Action。

◆ ……

如果我們要將這個流程改造成異步處理,那么就要讓它符合ASP.NET架構中的異步處理方式。ASP.NET架構對于異步請求的處理可以體現在好幾種方式上,例如異步頁面,異步Http Module等,而最適合目前場合的做法自然是異步Http Handler。為實現一個異步Handler,我們需要讓處理請求的Handler實現IHttpAsyncHandler接口,而不是傳統的IHttpHandler接口。IHttpAsyncHandler接口中的BeginProcessRequest和EndProcessRequest兩個方法構成了.NET中的APM(Aynchronous Programming Model,異步編程模型)模式,可以使用“二段式”的異步調用來處理一個HTTP請求。

您應該已經發現,如果我們要支持異步Action,就必須根據當前的請求信息來確認究竟是執行一個IHttpHandler對象還是IHttpAsyncHandler對象。而在ASP.NET MVC框架在默認情況下是在Http Handler(即MvcHandler對象)內部進行控制器的檢查,構造和調用。這為時已晚,我們必須講這些邏輯提前到Routing過程中才行。幸運的是,ASP.NET Routing所支持的IRouteHandler就像是ASP.NET中的IHttpHandlerFactory,可以根據情況生成不同的Handler來執行。因此,我們只要構建一個新的IRouteHandler類型即可。于是就誕生了AsyncMvcRouteHandler——可以想象的出,其中的部分代碼與框架中的MvcHandler相同,因為在一定程度上我們的確只是把原本在MvcHandler里做的事情給提前了:

public class AsyncMvcRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string controllerName = requestContext.RouteData.GetRequiredString("controller");

        var factory = ControllerBuilder.Current.GetControllerFactory();
        var controller = factory.CreateController(requestContext, controllerName);
        if (controller == null)
        {
            throw new InvalidOperationException(...);
        }

        var coreController = controller as Controller;
        if (coreController == null)
        {
            return new SyncMvcHandler(controller, factory, requestContext);
        }
        else
        {

            string actionName = requestContext.RouteData.GetRequiredString("action");
            return IsAsyncAction(coreController, actionName, requestContext) ?
                (IHttpHandler)new AsyncMvcHandler(coreController, factory, requestContext) :
                (IHttpHandler)new SyncMvcHandler(controller, factory, requestContext);
        }
    }

    internal static bool IsAsyncAction(
        Controller controller, string actionName, RequestContext requestContext)
    {
        ...
    }
}

在GetHttpHandler方法中,我們先從RouteData的controller字段中獲取控制器的名字,并通過注冊在ControllerBuilder上的Factory來創建一個實現了IController接口的控制器對象。由于我們需要使用Controller類中包含的ActionInvoker來輔助檢測Action的異步需求,因此我們會設法將其轉化為Controller類型。如果轉換成功,就會取出RouteData中的action字段的值,并通過IsAsyncAction方法來確認當前Action是否應該異步執行。如果是,則返回一個實現了IHttpAsyncHandler的AsyncMvcHandler對象,否則就返回一個實現IHttpHandler的SyncMvcHandler對象。

至于AsyncMvcRouteHandler的使用,只需在MapRoute時將Route Handler重新設置一下即可:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 routes.MapRoute(
        "Default",                                              // Route name
        "{controller}/{action}/{id}",                           // URL with parameters
        new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    ).RouteHandler = new AsyncMvcRouteHandler();
}

#p#

檢查是否為異步Action

從上面的代碼中我們已經形成了一個約定:如果要執行一個異步Action,那么控制器對象必須為Controller類型。這個約定的目的是為了使用Controller類中包含的IActionInvoker——確切地說,是ControllerActionInvoker類型里的功能。因此,另一個約定便是Controller的ActionInvoker對象必須返回一個ControllerActionInvoker的實例。

ControllerActionInvoker中有一些輔助方法,能夠返回對于一個Controller或Action的描述對象。從一個Action描述對象中我們可以獲取關于這個Action的各種信息,而它是否被標記了AsyncActionAttribute,就是我們判斷這個Action是否應該被異步執行的依據。如下:

private static object s_methodInvokerMutex = new object();
private static MethodInvoker s_controllerDescriptorGetter;

internal static bool IsAsyncAction(
    Controller controller, string actionName, RequestContext requestContext)
{
    var actionInvoker = controller.ActionInvoker as ControllerActionInvoker;
    if (actionInvoker == null) return false;

    if (s_controllerDescriptorGetter == null)
    {
        lock (s_methodInvokerMutex)
        {
            if (s_controllerDescriptorGetter == null)
            {
                BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
                MethodInfo method = typeof(ControllerActionInvoker).GetMethod(
                    "GetControllerDescriptor", bindingFlags);
                s_controllerDescriptorGetter = new MethodInvoker(method);
            }
        }
    }

    var controllerContext = new ControllerContext(requestContext, controller);
    var controllerDescriptor = (ControllerDescriptor)s_controllerDescriptorGetter.Invoke(
        actionInvoker, controllerContext);
    var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
    return actionDescriptor == null ? false :
        actionDescriptor.GetCustomAttributes(typeof(AsyncActionAttribute), false).Any();
}

ControllerActionInvoker類型中有個protected方法GetControllerDescriptor,它接受一個ControllerContext類型的參數,并返回一個ControllerDescriptor對象來描述當前控制器,而從該描述對象中可以通過FindAction方法獲得一個ActionDescriptor對象來描述即將執行的Action。如果是一個不存在的Action,那么就返回false,***就通過SyncMvcHandler對象來執行默認的行為。當且僅當該Action上擁有AsyncActionAttribute標記時,才說明它應該被異步執行,返回true。此外,這段代碼中用到了MethodInvoker,這是一個輔助類,它來源于Fast Reflection Library,它實現了反射調用功能,但是它的性能十分接近于方法的直接調用,我在這篇文章中詳細描述了這個項目的功能和使用。

這段代碼便涉及到ASP.NET MVC RC版本在Beta版本基礎上的改進。在原先的ControllerActionInvoker類中只有獲取Action方法的MethodInfo,而沒有RC中各描述對象這樣的抽象類型。從目前的設計上來看,我們使用的都是基于反射的抽象描述類型的子類。例如默認情況下,我們通過ActionDescriptor抽象類型訪問的實際上是ReflectedActionDescriptor類型的實例。這是一個很有用的改進,由于我們通過描述對象進行抽象,于是我們就可以:

◆ 使用不同的實現方式來描述各對象,默認情況下是使用基于反射(也就是“約定”)的實現,如果需要的話我們也可以使用基于配置文件的方式替換現有實現。

◆ 使用特定對象的描述方式可以不拘泥于內部細節,例如一個異步的Action可能就由兩個方法組成。

◆ 有了特定的描述對象,也方便添加額外的屬性,例如該Action是否應該異步執行,是否應該禁用Session State等等。

◆ ……

【編輯推薦】

  1. 為ASP.NET MVC擴展異步Action功能(下)
  2. 詳解ASP.NET MVC的請求生命周期
  3. ASP.NET MVC實例和新RC版本中視圖方面的改進
  4. ASP.NET MVC框架視頻教程
責任編輯:楊鵬飛 來源: 博客園
相關推薦

2009-02-17 09:22:14

ActionMVCASP.NET

2009-07-22 10:13:31

異步ActionASP.NET MVC

2009-03-06 10:28:30

MVCASP.NET異步Action

2009-07-22 09:11:02

Action方法ASP.NET MVC

2009-07-22 16:02:39

ASP.NET MVCPagedList

2009-07-31 12:43:59

ASP.NET MVC

2009-07-24 13:20:44

MVC框架ASP.NET

2009-07-20 12:59:53

ASP.NET MVCASP.NET框架的功

2009-07-22 18:02:27

論壇應用程序ASP.NET MVC

2010-04-06 15:20:56

ASP.NET MVC

2009-07-20 10:53:59

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2010-02-05 08:32:32

ASP.NET MVC

2017-03-06 11:13:57

ASP.NETCoreMVC

2009-07-28 16:40:11

ASP.NET異步頁面

2021-03-08 07:32:05

Actionweb框架

2015-06-17 17:01:48

ASP.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色视频成人在线观看免 | 亚洲欧洲成人 | 亚洲在线免费观看 | 久久久日韩精品一区二区三区 | 最近中文字幕免费 | 在线播放精品视频 | 在线播放国产一区二区三区 | 日韩在线中文字幕 | 精品欧美一区二区三区久久久 | 亚洲欧美一区二区三区在线 | www.日本三级 | 黑人巨大精品欧美一区二区一视频 | 国产精品久久久久久婷婷天堂 | 日韩免费视频一区二区 | 久草精品视频 | 亚洲人成人一区二区在线观看 | 在线观看免费av网站 | 人人精品 | 天天爽网站 | 欧美日韩高清免费 | 欧美午夜精品 | 国产在线精品一区二区三区 | 国产高清精品在线 | a免费视频| 涩涩视频网站在线观看 | 在线免费看黄 | 日韩一区中文字幕 | 久久精品视频在线观看 | 久久久久久久综合 | 国产日产精品一区二区三区四区 | 91久久婷婷| 国产三级精品三级在线观看四季网 | 国产人成在线观看 | 大久| 国产精品激情小视频 | 伊人免费在线观看高清 | 亚洲天堂网站 | 国产一区在线看 | 中文字幕91av | av大片 | 久久精品超碰 |