4

在这个问答中,我找到了一种让 ASP.NET MVC 支持异步处理的方法。但是,我不能让它工作。

基本上,这个想法是创建一个新的 IRouteHandler 实现,它只有一个方法GetHttpHandler。GetHttpHandler方法应该返回一个实现而不是 just 因为有 Begin/EndXXXX 模式 API。IHttpAsyncHandlerIHttpHandlerIHttpAsyncHandler

public class AsyncMvcRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new AsyncMvcHandler(requestContext);
    }

    class AsyncMvcHandler : IHttpAsyncHandler, IRequiresSessionState
    {
        public AsyncMvcHandler(RequestContext context)
        {
        }

        // IHttpHandler members
        public bool IsReusable { get { return false; } }
        public void ProcessRequest(HttpContext httpContext) { throw new NotImplementedException(); }

        // IHttpAsyncHandler members
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            throw new NotImplementedException();
        }

        public void EndProcessRequest(IAsyncResult result)
        {
            throw new NotImplementedException();
        }
    }
}

然后,在文件 Global.asax.cs 的 RegisterRoutes 方法中,注册这个类AsyncMvcRouteHandler

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new Route("{controller}/{action}/{id}", new AsyncMvcRouteHandler())
    {
        Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
    });
}

我在ProcessRequestBeginProcessRequestEndProcessRequest设置断点。仅执行ProcessRequest。换句话说,即使AsyncMvcHandler实现了IHttpAsyncHandler。ASP.NET MVC 不知道这一点,只是将其作为IHttpHandler实现处理。

如何使 ASP.NET MVC 将AsyncMvcHandler视为IHttpAsyncHandler以便我们可以进行异步页面处理?

4

3 回答 3

3

我遇到了同样的问题,但是我发现这是因为我的捕获所有路由处理程序:

routes.MapRoute(
    "Default",                                                  
    "{controller}/{action}",                           
    new { controller = "Home", action = "Index" }  
);

正在接收请求,而不是我添加的处理异步路由处理程序的自定义路由。也许通过在您的自定义路由定义中使用 .mvc,您创建了一个区别,以便使用它而不是同步包罗万象。

于 2009-01-29T00:17:14.140 回答
2

经过数小时的代码麻烦后,我发现了问题所在。

在我的 Visual Studio 2008 中,当我按下 Ctrl+F5 时,会启动应用程序开发服务器并弹出 IE 以访问“ http://localhost:3573/ ”。在这种情况下,将调用同步 API ProcessRequest。堆栈跟踪是这样的。

MyMvcApplication.DLL!MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.ProcessRequest(System.Web.HttpContext httpContext = {System.Web.HttpContext}) 第 59 行 C# System.Web.Mvc.dll!System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest(System. Web.IHttpHandler httpHandler, System.Web.HttpContextBase httpContext) + 0x19 字节
System.Web.Routing.dll!System.Web.Routing.UrlRoutingHandler.ProcessRequest(System.Web.HttpContextBase httpContext) + 0x66 字节
System.Web.Routing.dll !System.Web.Routing.UrlRoutingHandler.ProcessRequest(System.Web.HttpContext httpContext) + 0x28 字节
System.Web.Routing.dll!System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest(System.Web.HttpContext上下文)+ 0x8 字节
MyMvcApplication.DLL!MyMvcApplication._Default.Page_Load(object sender = {ASP.default_aspx}, System.EventArgs e = {System.EventArgs}) 第 13 行 + 0x1a 字节 C#

但是,当我将 IE 中的 URL 更改为“ http://localhost:3573/whatever.mvc ”时,它会命中BeginProcessRequest。堆栈跟踪是这样的。

MyMvcApplication.DLL!MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest(System.Web.HttpContext context = {System.Web.HttpContext},System.AsyncCallback cb = {Method = {Void OnAsyncHandlerCompletion(System.IAsyncResult)}},对象 extraData = null ) 第 66 行 C# System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x249 字节 System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web. HttpApplication.IExecutionStep step = {System.Web.HttpApplication.CallHandlerExecutionStep}, ref bool completedSynchronously = true) + 0x9c 字节
System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception 错误) + 0x133 字节
System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0x7c 字节
System.Web.dll!System.Web.HttpRuntime。 ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x17c 字节 System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x63 字节
System.Web。 dll!System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest WR) + 0x47 字节
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Request.Process() + 0xf1 字节 WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn) + 0x4e 字节

似乎只有带有“.mvc”后缀的url才能调用异步API。

于 2008-11-12T02:30:38.543 回答
0

我过去曾尝试过这样做,我设法要么让视图呈现,然后所有异步任务都会完成。或者异步任务要完成但视图不会呈现。

我基于原始 MVC 代码创建了一个 RouteCollectionExtensions。在我的 AsyncMvcHandler 中,我有一个用于 ProcessMethod 的空方法(没有例外)。

于 2008-11-10T19:07:18.953 回答