2015-07-18 8 views
10

Ho un percorso ASP.NET personalizzato che contiene operazioni di IO. Per ora, si supponga che queste operazioni IO non possano essere memorizzate nella cache (cioè troppo grandi).Async RouteBase in ASP.NET con GetRouteDataAsync e GetVirtualPathAsync?

In un certo senso sto cercando un una classe AsyncRouteBase con

public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext) 
public async override Task<VirtualPathData> GetVirtualPathAsync(RequestContext requestContext, RouteValueDictionary routeValues); 
  • fa qualcosa di simile già esiste? (non lo trova)
  • C'è qualche posto all'interno della pipeline ASP.NET dove posso creare da solo?

sto usando ASP.NET MVC 5.2.3.0

+0

Quanto tempo impiegherà l'IO? Se è veloce (probabilmente nel routing), non ha senso utilizzare l'IO asincrono (http://stackoverflow.com/questions/25086866/why-does-the-ef-6-tutorial-use-asychronous-calls/25087273) . – usr

+0

Potrebbe essere più chiamate di database con circa 50ms ciascuna. –

+0

OK, probabilmente non ha senso per l'IO asincrono. Comunque, bella domanda. – usr

risposta

0

Purtroppo, non c'è alcun modo per ignorare un metodo non async con una async uno. Credo che la soluzione migliore è quella di avere un metodo di async non override e mettere in che dal non async uno simile:

public override RouteData GetRouteData(HttpContextBase httpContext) { 
    return GetRouteDataAsync(httpContext); 
    //return await GetRouteDataAsync(httpContext); 
} 

public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext){ 
    //operations here 
} 

Nota: questo può causare problemi però. Se il codice originale non si aspettava l'esecuzione di un codice async, l'introduzione di questo modello potrebbe rompere le aspettative. Evitalo se possibile.

Come consigli, vedere Simplify Asynchronous Programming with Tasks

1

Non è possibile creare AsyncRouteBase, perché le rotte utilizzate da ASP.NET MVC sono sincroni. Devi capire che per poter creare metodi asincroni, qualcuno deve consumarli in modo asincrono, non puoi magicamente rendere tutto asincrono aggiungendo il metodo asincrono.

Il routing non può essere asincrono per vari motivi, le route vengono memorizzate nella cache e vengono create una sola volta al momento dell'esecuzione della prima richiesta. Attenzione, i percorsi vengono memorizzati nella cache, non cambiano e non possono essere modificati in runtime perché vengono eseguiti per primi, se il routing eseguirà chiamate db asincrone, ogni richiesta dovrà attendere che venga soddisfatta la condizione di routing che rallenterà l'intera applicazione .

E in genere non è necessario AsyncRouteBase, ma è possibile creare Async Route Handler.

public class AsyncRouteHandler : IRouteHandler 
{ 
    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) 
    { 
     return new AsyncHttpHandler(); 
    } 
} 

public class AsyncHttpHandler : HttpTaskAsyncHandler{ 
    public override async Task ProcessRequestAsync(HttpContext context) 
    {   
    } 
} 

Tuttavia, utilizzando MVC conduttura all'interno di questo richiederà un sacco di lavoro, ma si può facilmente ignorare che il servizio e la risposta da qui. Puoi usare controller factory all'interno di questo e creare i tuoi metodi per eseguire ciò che ti serve.

Un'altra alternativa è utilizzare facilmente MEF o altre forme di DI per gestire il codice più grande e richiamare i rispettivi metodi all'interno di AsyncHttpHandler.

+0

Ciao Akash, grazie per la tua risposta. Solo una nota: un personalizzato 'RouteBase' non viene memorizzato nella cache per impostazione predefinita per MVC. Come lo so? Effettuo chiamate al database durante il mio (piuttosto) routing complicato :) –

+0

Informazioni sul motivo per cui desidero renderlo asincrono: lo stesso motivo per cui desidero rendere tutte le mie azioni asincrone - in modo da non bloccare un thread non necessario. La richiesta è comunque bloccata (per alcuni ms) - piuttosto una parte di servizio di un'altra richiesta nel frattempo. –

+0

La parte con 'HttpTaskAsyncHandler' sembra piuttosto interessante e che potrebbe essere la risposta - Devo capire come e se posso implementarlo in MVC mantenendo tutto il comportamento esistente. –

Problemi correlati