2013-07-25 18 views
5

Mam moduł HttpModule synchroniczny, który zawiera następujący kod. Asynchroniczny moduł HttpModule 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); 
    } 

Kiedy próbuję uruchomić moduł z pustym aplikacji MVC4 (NET 4.5) pojawia się następujący błąd.

Operacji asynchronicznej nie można teraz uruchomić. Operacje asynchroniczne można uruchamiać tylko w ramach modułu obsługi asynchronicznej lub modułu lub podczas określonych zdarzeń w cyklu życia strony. Jeśli wystąpił ten wyjątek podczas wykonywania strony, upewnij się, że strona jest oznaczona jako % @ Page Async = "true"%>.

Brakuje mi czegoś, ale wydaje mi się, że błąd nie powinien wystąpić.

Mam wykopaliska, ale nie mogę znaleźć niczego, aby pomóc, czy ktoś ma jakieś pomysły?

Odpowiedz

10

Masz więc kod asynchroniczny w procedurze obsługi zdarzenia synchronicznego HttpModule, a program ASP.NET generuje wyjątek wskazujący, że operacje asynchroniczne mogą być uruchamiane tylko w asynchronicznym module obsługi. Wydaje mi się to całkiem proste.

Aby to naprawić, nie należy bezpośrednio subskrybować numeru BeginRequest; zamiast tego utwórz "obsługujący" kod Task, zawiń go w EventHandlerTaskAsyncHelper i przekaż go do AddOnBeginRequestAsync.

coś takiego:

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". 
} 

i subskrybować:

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

To musi być kilka razy Pomogłeś mi teraz, dzięki! Powinienem był powiedzieć "przepraszam". Kod został napisany w wersji 4.0 i używa bibliotek BCL do obsługi asynchronicznego słowa kluczowego, więc mogłem obsługiwać zarówno 4.0, jak i 4.5. Jako taki EventHandlerTaskAsyncHelper nie jest dostępny dla mnie. –

+2

Ah, niestety, 'Microsoft.Bcl.Async' ma [niezdefiniowane zachowanie w ASP.NET 4.0] (http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime -targetframework.aspx). Na platformie ASP.NET * masz * uruchamianie w .NET 4.5, a nie .NET 4.0. –

+0

Ach ok ... Przetestuj to, jeśli usunę element 'targetFramework =" 4.5 "' z węzła '' w pliku web.config, który działa. Czy to oznacza, że ​​w NET 4.0 mój httpModule nie jest tak naprawdę asynchroniczny? Czy to oznacza również, że nie mogę używać asynchronicznego httpModule bez 'EventHandlerTaskAsyncHelper' z MVC lub istnieje inny sposób. Nadal jestem trochę zmieszany, że rzucam błąd, aby być szczerym. Wiadomość wydaje się mówić, że httpModules są w porządku. –