8

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

    /// <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) 运行模块时,出现以下错误。

此时无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保将页面标记为 <%@ Page Async="true" %>。

我似乎遗漏了一些东西,但通过我的阅读,错误实际上不应该发生。

我已经进行了挖掘,但我似乎找不到任何帮助,有人有什么想法吗?

4

1 回答 1

17

因此,您在同步 HttpModule 事件处理程序中有异步代码,并且 ASP.NET 会引发异常,指示异步操作只能在异步处理程序/模块中启动。对我来说似乎很简单。

要解决此问题,您不应BeginRequest直接订阅;相反,创建一个Task返回“处理程序”,将其包装在 中EventHandlerTaskAsyncHelper,并将其传递给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);
于 2013-07-25T17:49:39.610 回答