在控制器中调用异步方法

时间:2012-11-30 14:41:30

标签: c# asp.net-mvc-4 async-await

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

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

调用我的控制器时出现以下错误:

  

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

现在我无法控制CallSomeMethodWhichDoesAsyncOperations并且方法本身不是异步的,但内部会有一些异步触发并忘记。我该怎么办才能修复它?尝试将控制器更改为AsyncController和/或使控制器中的方法异步。

编辑:

当我尝试使用AsyncController时,我首先尝试使用相同的结果

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

然后

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

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

1 个答案:

答案 0 :(得分:24)

  

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

联系编写该文件的人并使他们修复它。

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

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

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

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

只有一个正确的解决方案:更改CallSomeMethodWhichDoesAsyncOperations