异步HTTP模块MVC

问题描述:

我有一个包含以下code同步的HttpModule。

I have a synchronous HttpModule that contains the following code.

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

当我尝试从空MVC4应用程序运行模块(NET 4.5)我收到以下错误。

When I try to run the module from an empty MVC4 application (NET 4.5) I get the following error.

这是异步操作不能在这个时间开始。异步
  操作可能只异步处理程序中启动或
  模块或过程中页面生命周期的某些事件。如果这
  异常发生在执行页上,确保该页面
  标&LT;%@页面异步=真正的%>

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>.

我想的东西似乎而是由我的阅读,不应该实际发生的错误。

I'm missing something it seems but by my reading that the error shouldn't actually occur.

我有一个挖过来,但我似乎无法找到任何事情来帮助,没有任何人有什么想法?

I've had a dig around but I cannot seem to find anything to help, does anyone have any ideas?

所以,你必须在一个同步的HttpModule事件处理异步code和ASP.NET抛出一个异常,表明异步操作只能异步内启动处理器/模块。看来pretty简单的给我。

So you have asynchronous code in a synchronous HttpModule event handler, and ASP.NET throws an exception indicating that asynchronous operations may only be started within an asynchronous handler/module. Seems pretty straightforward to me.

要解决这个问题,你不应该订阅的BeginRequest 直接;相反,创建一个工作 -returning处理程序,在它包装EventHandlerTaskAsyncHelper$c$c>,并把它传递给AddOnBeginRequestAsync$c$c>.

To fix this, you should not subscribe to BeginRequest directly; instead, create a Task-returning "handler", wrap it in EventHandlerTaskAsyncHelper, and pass it to AddOnBeginRequestAsync.

事情是这样的:

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

和订阅:

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