Question

Dans cette question & amp; répondre , j’ai trouvé un moyen de faire en sorte que ASP.NET MVC prenne en charge le traitement asynchrone. Cependant, je ne peux pas le faire fonctionner.

Fondamentalement, l’idée est de créer une nouvelle implémentation d’IRouteHandler qui n’a qu’une méthode GetHttpHandler . La méthode GetHttpHandler doit renvoyer une implémentation IHttpAsyncHandler au lieu de simplement IHttpHandler, car IHttpAsyncHandler possède l'API de modèle 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();
        }
    }
}

Ensuite, dans la méthode RegisterRoutes du fichier Global.asax.cs, enregistrez cette classe AsyncMvcRouteHandler .         public static void RegisterRoutes (itinéraires RouteCollection)         {             routes.IgnoreRoute (" {ressource} .axd / {* pathInfo} ");

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

J'ai défini un point d'arrêt sur ProcessRequest , BeginProcessRequest et EndProcessRequest . . Seul ProcessRequest est exécuté. En d'autres termes, même si AsyncMvcHandler implémente IHttpAsyncHandler . ASP.NET MVC ne le sait pas et le gère simplement comme une implémentation IHttpHandler.

Comment faire pour qu'ASP.NET MVC traite AsyncMvcHandler en tant que IHttpAsyncHandler , afin que nous puissions avoir un traitement de page asynchrone?

Était-ce utile?

La solution 2

Après des heures de galère avec le code, j'ai découvert le problème.

Dans Visual Studio 2008, lorsque j'appuie sur Ctrl + F5, le serveur de développement d'applications est lancé et IE est affiché pour permettre l'accès http: // localhost: 3573 / " ;. Dans ce cas, l'API de synchronisation ProcessRequest est appelée. La trace de la pile est comme ça.

  
    

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

  

Toutefois, lorsque je modifie l'URL dans IE pour qu'il soit " http: // localhost: 3573 /. mvc " ;, il atteint le BeginProcessRequest . La trace de la pile est comme ça.

  
    

MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest (System.Web.HttpContext     context = {System.Web.HttpContext},     System.AsyncCallback cb = {Méthode =     {Vide     OnAsyncHandlerCompletion (System.IAsyncResult)}},     objet extraData = null) Ligne 66 C #       System.Web.dll! System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute ()     + 0x249 octets System.Web.dll! System.Web.HttpApplication.ExecuteStep (System.Web.HttpApplication.IExecutionStep     step =     {System.Web.HttpApplication.CallHandlerExecutionStep},     ref bool completedSynchronously =     true) + 0x9c octets
      System.Web.dll! System.Web.HttpApplication.ApplicationStepManager.ResumeSteps (System.Exception     erreur) + 0x133 octets
      System.Web.dll! System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest (System.Web.HttpContext     contexte, System.AsyncCallback cb,     objet extraData) + 0x7c octets
      System.Web.dll! System.Web.HttpRuntime.ProcessRequestInternal (System.Web.HttpWorkerRequest     wr =     {Microsoft.VisualStudio.WebHost.Request})     + 0x17c octets System.Web.dll! System.Web.HttpRuntime.ProcessRequestNoDemand (System.Web.HttpWorkerRequest     wr) + 0x63 octets
      System.Web.dll! System.Web.HttpRuntime.ProcessRequest (System.Web.HttpWorkerRequest     wr) + 0x47 octets
      WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Request.Process ()     + 0xf1 octets WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Host.ProcessRequest (Microsoft.VisualStudio.WebHost.Connection     conn) + 0x4e octets

  

Il semble que seul l'URL avec ".mvc". suffixe peut faire appel à une API asynchrone.

Autres conseils

J'ai eu le même problème, mais j’ai trouvé que c’était parce que mon gestionnaire de routage attrape tous:

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

La demande était prise en charge, pas la route personnalisée que j'ai ajoutée et qui traitait du gestionnaire de route asynchrone. Peut-être qu'en utilisant le fichier .mvc dans la définition de votre route personnalisée, vous avez créé une distinction, de sorte qu'elle soit utilisée plutôt que dans le bloc fourre-tout synchrone.

J’ai essayé de le faire par le passé, je réussissais à obtenir le rendu de la vue, puis toutes les tâches asynchrones se terminaient. Ou les tâches asynchrones à terminer mais la vue ne sera pas rendue.

J'ai créé une RouteCollectionExtensions basée sur le code MVC d'origine. Dans mon AsyncMvcHandler, j'avais une méthode vide (sans exception) pour ProcessMethod.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top