Pergunta

Neste perguntas e respostas , eu encontrei um maneira de fazer ASP.NET MVC suportar o processamento assíncrono. No entanto, não posso fazê-lo funcionar.

Basicamente, a idéia é criar uma nova implementação do IRouteHandler que tem apenas um método GetHttpHandler . O GetHttpHandler método deve retornar uma implementação IHttpAsyncHandler em vez de apenas IHttpHandler, porque IHttpAsyncHandler tem Begin / EndXXXX padrão 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();
        }
    }
}

Em seguida, no método RegisterRoutes de arquivo Global.asax.cs, cadastre-se esta classe AsyncMvcRouteHandler . RegisterRoutes public static void (rotas RouteCollection) { routes.IgnoreRoute ( "{recurso} .axd / {* pathInfo}");

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

I ponto de interrupção definido em ProcessRequest , BeginProcessRequest e EndProcessRequest . Só ProcessRequest é executado. Em outra palavra, mesmo que AsyncMvcHandler implementos IHttpAsyncHandler . O ASP.NET MVC não sabem que e apenas lidar com isso como uma implementação IHttpHandler.

Como fazer ASP.NET MVC deleite AsyncMvcHandler como IHttpAsyncHandler para que possamos ter assíncrona processamento de página?

Foi útil?

Solução 2

Depois de horas de aborrecimento com o código, eu descobri o problema.

Na minha Visual Studio 2008, quando eu pressionar Ctrl + F5, o Desenvolvimento Application Server é lançado e IE é apareceu para o acesso " http: // localhost: 3573 / ". Neste caso, a API sync ProcessRequest é invocado. O rastreamento de pilha é assim.

MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.ProcessRequest (System.Web.HttpContext httpContext = {System.Web.HttpContext}) Linha 59 C # System.Web.Mvc.dll! System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest (System.Web.IHttpHandler httpHandler, System.Web.HttpContextBase httpContext) + 0x19 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContextBase httpContext) + 0x66 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContext httpContext) + 0x28 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest (System.Web.HttpContext contexto) + 0x8 bytes
MyMvcApplication.DLL! MyMvcApplication._Default.Page_Load (object = Remetente {}, ASP.default_aspx System.EventArgs e = {System.EventArgs}) Linha 13 + 0x1a bytes C #

No entanto, quando eu mudar a URL no IE para ser " http: // localhost: 3573 / whatever.mvc ", ela atinge o BeginProcessRequest . O rastreamento de pilha é assim.

MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest (System.Web.HttpContext contexto = {} System.Web.HttpContext, System.AsyncCallback cb = {method = {Vazio OnAsyncHandlerCompletion (System.IAsyncResult)}}, objeto extraData = nulo) Linha 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 etapa = {System.Web.HttpApplication.CallHandlerExecutionStep}, ref bool completedSynchronously = true) + 0x9C bytes
System.Web.dll! System.Web.HttpApplication.ApplicationStepManager.ResumeSteps (System.Exception erro) + 0x133 bytes
System.Web.dll! System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest (System.Web.HttpContext contexto, System.AsyncCallback cb, objeto 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 bytes
System.Web.dll! System.Web.HttpRuntime.ProcessRequest (System.Web.HttpWorkerRequest wr) + 0x47 bytes
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

Parece que só url com ".mvc" sufixo pode fazer API assíncrona invocada.

Outras dicas

Eu tive o mesmo problema, no entanto, achamos que era porque o meu pegar todos manipulador de rota:

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

Foi pegar o pedido, não a rota personalizada Acrescentei que lidou com o manipulador de rota assíncrona. Talvez usando a .mvc em sua rota personalizada defintion você criou uma distinção para que ele foi usado em vez do síncrona pega-tudo.

Eu tentei fazer isso no passado, eu conseguir ter tanto o objectivo de render e, em seguida, todas as tarefas assíncronas iria terminar. Ou as tarefas assíncronos para concluir, mas a vista não iria render.

Eu criei um RouteCollectionExtensions baseado no código MVC originais. Na minha AsyncMvcHandler, eu tinha um método vazio (sem exceção) para ProcessMethod.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top