如何使ASP.NET MVC从IRouteHandler.GetHttpHandler()中识别IHttpAsyncHandler?
-
07-07-2019 - |
题
在此问题&回答,我发现了一种使ASP.NET MVC支持异步处理的方法。但是,我无法使其发挥作用。
基本上,我们的想法是创建一个新的IRouteHandler实现,它只有一个方法 GetHttpHandler 。 GetHttpHandler 方法应返回IHttpAsyncHandler实现,而不仅仅是IHttpHandler,因为IHttpAsyncHandler具有Begin / EndXXXX模式API。
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(QUOT; {资源}个.axd / {* PATHINFO}&QUOT);
routes.Add(new Route("{controller}/{action}/{id}", new AsyncMvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
});
}
我在 ProcessRequest , BeginProcessRequest 和 EndProcessRequest 设置断点即可。仅执行 ProcessRequest 。换句话说,即使 AsyncMvcHandler 实现 IHttpAsyncHandler 。 ASP.NET MVC不知道这一点,只是将它作为IHttpHandler实现来处理。
如何使ASP.NET MVC将 AsyncMvcHandler 视为 IHttpAsyncHandler ,以便我们可以进行异步页面处理?
解决方案 2
经过几个小时的代码麻烦,我发现了问题。
在我的Visual Studio 2008中,当我按下Ctrl + F5时,将启动应用程序开发服务器并弹出IE以访问“ HTTP://本地主机:3573 / &QUOT ;.在这种情况下,会调用同步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(对象 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 = {无效 OnAsyncHandlerCompletion(System.IAsyncResult)}}, object extraData = null)第66行C# System.Web.dll中!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x249 bytes System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {} System.Web.HttpApplication.CallHandlerExecutionStep, ref bool completedSynchronously = true)+ 0x9c bytes
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 bytes
System.Web.dll中!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x17c bytes 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 bytes WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn)+ 0x4e bytes
似乎只有带有“.mvc”的网址。后缀可以调用异步API。
其他提示
我有同样的问题,但我发现这是因为我抓住所有路线处理程序:
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index" }
);
正在接收请求,而不是我添加的处理异步路由处理程序的自定义路由。也许通过在自定义路由定义中使用.mvc,您创建了一个区别,以便使用它而不是同步catch-all。
我过去曾试图这样做,我设法让视图渲染,然后所有异步任务都完成。或者完成异步任务但视图不会呈现。
我基于原始的MVC代码创建了一个RouteCollectionExtensions。在我的AsyncMvcHandler中,我有一个ProcessMethod的空方法(没有例外)。