在控制器中调用异步方法

Chr*_*ian 23 c# async-await asp.net-mvc-4

我有一个控制器,如下所示:

public MyController : Controller
{
    public ActionResult DoSomething()
    {
        CallSomeMethodWhichDoesAsyncOperations();
        return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

调用我的控制器时,我收到以下错误:

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

现在我没有控制权CallSomeMethodWhichDoesAsyncOperations,方法本身不是异步,但内部做了一些异步火灾和遗忘.我该怎么办才能修复它?尝试将控制器更改为AsyncController和/或使控制器中的方法异步.

编辑:

当我第一次尝试使用AsyncController时,结果相同

public MyController : AsyncController
{
    public ActionResult DoSomething()
    {
        CallSomeMethodWhichDoesAsyncOperations();
        return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后

public MyController : AsyncController
{
    public async Task<ActionResult> DoSomething()
    {
        CallSomeMethodWhichDoesAsyncOperations();
        return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

这确实将异常更改为以下"在异步操作仍处于挂起状态时完成的异步模块或处理程序".

Ste*_*ary 25

现在我无法控制CallSomeMethodWhichDoesAsyncOperations,并且方法本身不是异步,但内部会执行一些异步触发并忘记.我该怎么办才能修复它?

联系编写它的人并让他们修复它.

说真的,那是最好的选择.对此没有好的解决方法 - 只有一个黑客.

你可以破解它像这样工作:

public MyController : Controller
{
  public async Task<ActionResult> DoSomething()
  {
    await Task.Run(() => CallSomeMethodWhichDoesAsyncOperations());
    return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
  }
}
Run Code Online (Sandbox Code Playgroud)

不建议这样做.此解决方案将工作推送到后台线程,因此当async操作恢复时,它们将不具有HttpContext等等.此解决方案在仍有处理要完成时完成请求.如果服务器在错误的时间停止/回收,则此解决方案将无法正常运行.

只有一个合适的解决方案:改变CallSomeMethodWhichDoesAsyncOperations.

  • @StephenCleary应该有一个徽章,以便获得比Jon Skeet迟的答复并被接受 (2认同)