2013-07-25 10 views
5

Ho un HttpModule sincrono che contiene il seguente codice. HttpModule asincrono MVC

/// <summary> 
    /// Occurs as the first event in the HTTP pipeline chain of execution 
    /// when ASP.NET responds to a request. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e">An <see cref="T:System.EventArgs">EventArgs</see> that 
    /// contains the event data.</param> 
    private async void ContextBeginRequest(object sender, EventArgs e) 
    { 
     HttpContext context = ((HttpApplication)sender).Context; 
     await this.ProcessImageAsync(context); 
    } 

Quando provo ad eseguire il modulo da un'applicazione MVC4 vuota (NET 4.5) ottengo il seguente errore.

Un'operazione asincrona non può essere avviata in questo momento. Le operazioni asincrone possono essere avviate solo all'interno di un gestore asincrono o del modulo o durante determinati eventi nel ciclo di vita della Pagina. Se si verifica questa eccezione durante l'esecuzione di una pagina, verificare che la pagina sia contrassegnata con <% @ Page Async = "true"%>.

Mi manca qualcosa sembra, ma dalla mia lettura che l'errore non dovrebbe effettivamente verificarsi.

Ho fatto un giro in giro ma non riesco a trovare nulla per aiutare, qualcuno ha qualche idea?

risposta

10

Quindi si dispone di codice asincrono in un gestore di eventi HttpModule sincrono e ASP.NET genera un'eccezione che indica che le operazioni asincrone possono essere avviate solo all'interno di un gestore/modulo asincrono. A me sembra piuttosto semplice.

Per risolvere questo problema, non è necessario abbonarsi direttamente a BeginRequest; invece, crea un Task -returning "gestore", inseriscilo in EventHandlerTaskAsyncHelper e passalo a AddOnBeginRequestAsync.

Qualcosa di simile a questo:

private async Task ContextBeginRequest(object sender, EventArgs e) 
{ 
    HttpContext context = ((HttpApplication)sender).Context; 
    await ProcessImageAsync(context); 

    // Side note; if all you're doing is awaiting a single task at the end of an async method, 
    // then you can just remove the "async" and replace "await" with "return". 
} 

e per iscriversi:

var wrapper = new EventHandlerTaskAsyncHelper(ContextBeginRequest); 
application.AddOnBeginRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler); 
+0

questo deve essere un paio di volte che mi hai aiutato oggi, grazie! Avrei dovuto dire scusa, il codice è in realtà scritto in Net 4.0 e utilizza le librerie BCL per supportare la parola chiave async in modo da poter supportare sia la 4.0 che la 4.5. Come tale EventHandlerTaskAsyncHelper non è disponibile per me. –

+2

Ah, purtroppo, 'Microsoft.Bcl.Async' ha [comportamento non definito su ASP.NET 4.0] (http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime -targetframework.aspx). Su ASP.NET, * deve * essere eseguito su .NET 4.5, non su .NET 4.0. –

+0

Ah ok ... Quindi, testando questo se rimuovo 'targetFramework =" 4.5 "' dal nodo '' nel web.config funziona. Significa che in NET 4.0 il mio httpModule non è, in realtà, asincrono? Significa anche che non posso usare un httpModule asincrono senza "EventHandlerTaskAsyncHelper' con MVC o c'è un altro modo. Sono ancora all'ombra, confuso che stia commettendo un errore per essere onesto. Il messaggio sembra dire che i httpModules sono ok. –