Вызов метода async в контроллере
У меня есть контроллер с чем-то вроде следующего:
public MyController : Controller
{
public ActionResult DoSomething()
{
CallSomeMethodWhichDoesAsyncOperations();
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
При вызове моего контроллера я получаю следующую ошибку:
Асинхронная операция не может быть запущена в это время. Асинхронные операции может запускаться только в асинхронном обработчике или модуле или во время определенных события в жизненном цикле страницы. Если это исключение возникло при выполнении страницы, убедитесь, что страница отмечена <%@ Page Async="true" %>
.
Теперь у меня нет контроля над CallSomeMethodWhichDoesAsyncOperations
, и сам метод не является асинхронным, но внутренне выполняет некоторый асинхронный огонь и забывает. Что я могу сделать, чтобы исправить это? Попробовали сменить контроллер на AsyncController
и/или сделать метод в контроллере async.
Edit:
Когда я попытался использовать 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
Теперь у меня нет контроля над CallSomeMethodWhichDoesAsyncOperations, и сам метод не является асинхронным, но внутренне выполняет некоторый асинхронный огонь и забывает. Что я могу сделать, чтобы исправить это?
Свяжитесь с человеком, который его написал, и заставьте его исправить.
Серьезно, что лучший вариант. Нет ничего хорошего для этого - только хак.
Вы можете взломать его так:
public MyController : Controller
{
public async Task<ActionResult> DoSomething()
{
await Task.Run(() => CallSomeMethodWhichDoesAsyncOperations());
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
Это не рекомендуется. Это решение отбрасывает работу на фоновый поток, поэтому при возобновлении операций async
у них не будет HttpContext
и т.д. Это решение завершает запрос пока еще предстоит выполнить обработку. Это решение не будет корректно работать, если сервер будет остановлен/переработан в самое неподходящее время.
Существует только одно правильное решение: change CallSomeMethodWhichDoesAsyncOperations
.