Calling async method in controller

陌路散爱 提交于 2019-12-31 12:01:44

问题


I have a controller with something like the following:

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

When calling my controller I get the following error:

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

Now I dont have control over CallSomeMethodWhichDoesAsyncOperations and the method itself is not async but internally does some async fire and forget. What can I do to fix it? Have tried to change the controller to an AsyncController and/or making the method in the controller async.

Edit:

When I attempted to use an AsyncController I first tried, with the same result

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

And then

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

Which did change the exception to the following "An asynchronous module or handler completed while an asynchronous operation was still pending."


回答1:


Now I dont have control over CallSomeMethodWhichDoesAsyncOperations and the method itself is not async but internally does some async fire and forget. What can I do to fix it?

Contact the person who wrote it and make them fix it.

Seriously, that's the best option. There's no good fix for this - only a hack.

You can hack it to work like this:

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

This is not recommended. This solution pushes off work to a background thread, so when the async operations resume, they will not have an HttpContext, etc. This solution completes the request while there is still processing to be done. This solution will not behave correctly if the server is stopped/recycled at just the wrong time.

There is only one proper solution: change CallSomeMethodWhichDoesAsyncOperations.



来源:https://stackoverflow.com/questions/13647346/calling-async-method-in-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!