Domanda

In questa question & amp; risposta , ho trovato un modo per fare in modo che ASP.NET MVC supportasse l'elaborazione asincrona. Tuttavia, non riesco a farlo funzionare.

Fondamentalmente, l'idea è quella di creare una nuova implementazione di IRouteHandler che ha un solo metodo GetHttpHandler . Il metodo GetHttpHandler dovrebbe restituire un'implementazione IHttpAsyncHandler anziché solo IHttpHandler, poiché IHttpAsyncHandler ha un'API modello Begin / EndXXXX.

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();
        }
    }
}

Quindi, nel metodo RegisterRoutes del file Global.asax.cs, registra questa classe AsyncMvcRouteHandler .         RegisterRoutes vuoto statico pubblico (route RouteCollection)         {             routes.IgnoreRoute (" {resource} axd / {*} pathinfo ");

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

Ho impostato il punto di interruzione su ProcessRequest , BeginProcessRequest e EndProcessRequest . Viene eseguito solo ProcessRequest . In altre parole, anche se AsyncMvcHandler implementa IHttpAsyncHandler . ASP.NET MVC non lo sa e lo gestisce come un'implementazione IHttpHandler.

Come fare in modo che ASP.NET MVC tratti AsyncMvcHandler come IHttpAsyncHandler in modo da poter avere l'elaborazione asincrona della pagina?

È stato utile?

Soluzione 2

Dopo ore di seccature con il codice, ho scoperto il problema.

Nel mio Visual Studio 2008, quando premo Ctrl + F5, viene avviato Application Development Server e IE viene visualizzato per accedere a " http: // localhost: 3573 / " ;. In questo caso, viene richiamata l'API di sincronizzazione ProcessRequest . La traccia dello stack è così.

  
    

MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.ProcessRequest (System.Web.HttpContext     httpContext =     {System.Web.HttpContext}) Riga 59 C #       System.Web.Mvc.dll! System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest (System.Web.IHttpHandler     HttpHandler,     System.Web.HttpContextBase     httpContext) + 0x19 byte
      System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContextBase     httpContext) + 0x66 byte
      System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContext     httpContext) + 0x28 byte
      System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest (System.Web.HttpContext     contesto) + 0x8 byte
      MyMvcApplication.DLL! MyMvcApplication._Default.Page_Load (oggetto     mittente = {ASP.default_aspx},     System.EventArgs e =     {System.EventArgs}) Riga 13 + 0x1a     byte C #

  

Tuttavia, quando cambio l'URL in IE per essere " http: // localhost: 3573 / qualunque. mvc " ;, colpisce il BeginProcessRequest . La traccia dello stack è così.

  
    

MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest (System.Web.HttpContext     context = {System.Web.HttpContext},     System.AsyncCallback cb = {Metodo =     {Void     OnAsyncHandlerCompletion (System.IAsyncResult)}},     object extraData = null) Riga 66 C #       System.Web.dll! System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute ()     + 0x249 byte System.Web.dll! System.Web.HttpApplication.ExecuteStep (System.Web.HttpApplication.IExecutionStep     step =     {} System.Web.HttpApplication.CallHandlerExecutionStep,     ref bool completatoSincrono = =     true) + 0x9c byte
      System.Web.dll! System.Web.HttpApplication.ApplicationStepManager.ResumeSteps (System.Exception     errore) + 0x133 byte
      System.Web.dll! System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest (System.Web.HttpContext     contesto, System.AsyncCallback cb,     oggetto extraData) + 0x7c byte
      System.Web.dll! System.Web.HttpRuntime.ProcessRequestInternal (System.Web.HttpWorkerRequest     wr =     {} Microsoft.VisualStudio.WebHost.Request)     + 0x17c byte System.Web.dll! System.Web.HttpRuntime.ProcessRequestNoDemand (System.Web.HttpWorkerRequest     wr) + 0x63 byte
      System.Web.dll! System.Web.HttpRuntime.ProcessRequest (System.Web.HttpWorkerRequest     wr) + 0x47 byte
      WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Request.Process ()     + 0xf1 byte WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Host.ProcessRequest (Microsoft.VisualStudio.WebHost.Connection     conn) + 0x4e byte

  

Sembra che solo l'URL con " .mvc " il suffisso può far invocare l'API asincrona.

Altri suggerimenti

Ho avuto lo stesso problema, tuttavia ho scoperto che era perché il mio gestore di tutte le rotte cattura:

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

Stava raccogliendo la richiesta, non il percorso personalizzato che ho aggiunto che si occupava del gestore del percorso asincrono. Forse usando il .mvc nella definizione del tuo percorso personalizzato hai creato una distinzione in modo che fosse usato piuttosto che il sincrono catch-all.

Ho provato a farlo in passato, riesco a ottenere la visualizzazione per il rendering e quindi tutte le attività asincrone sarebbero finite. O le attività asincrone devono essere completate ma la vista non viene visualizzata.

Ho creato un RouteCollectionExtensions basato sul codice MVC originale. Nel mio AsyncMvcHandler, avevo un metodo vuoto (nessuna eccezione) per ProcessMethod.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top