net - understanding async await c#
Llamando al método asíncrono en el controlador (1)
Tengo un controlador con algo como lo siguiente:
public MyController : Controller
{
public ActionResult DoSomething()
{
CallSomeMethodWhichDoesAsyncOperations();
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
Cuando llamo a mi controlador recibo el siguiente error:
No se puede iniciar una operación asincrónica en este momento. Las operaciones asíncronas solo pueden iniciarse dentro de un controlador o módulo asíncrono o durante ciertos eventos en el ciclo de vida de la página. Si se produjo esta excepción al ejecutar una página, asegúrese de que la página esté marcada
<%@ Page Async="true" %>
.
Ahora no tengo control sobre CallSomeMethodWhichDoesAsyncOperations
y el método en sí no es asíncrono, pero internamente hace algo de asincronización y olvida. ¿Que puedo hacer para arreglarlo? He intentado cambiar el controlador a un AsyncController
y / o hacer que el método en el controlador sea asincrónico.
Editar:
Cuando intenté usar un AsyncController lo intenté por primera vez, con el mismo resultado
public MyController : AsyncController
{
public ActionResult DoSomething()
{
CallSomeMethodWhichDoesAsyncOperations();
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
Y entonces
public MyController : AsyncController
{
public async Task<ActionResult> DoSomething()
{
CallSomeMethodWhichDoesAsyncOperations();
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
Lo cual cambió la excepción a lo siguiente "Un módulo o manejador asíncrono se completó mientras una operación asíncrona aún estaba pendiente".
Ahora no tengo control sobre CallSomeMethodWhichDoesAsyncOperations y el método en sí no es asíncrono, pero internamente hace algo de asincronización y olvida. ¿Que puedo hacer para arreglarlo?
Póngase en contacto con la persona que lo escribió y haga que lo arreglen.
En serio, esa es la mejor opción. No hay una buena solución para esto, solo un truco.
Puede hackearlo para que funcione así:
public MyController : Controller
{
public async Task<ActionResult> DoSomething()
{
await Task.Run(() => CallSomeMethodWhichDoesAsyncOperations());
return Json(new { success = successful }, JsonRequestBehavior.AllowGet);
}
}
Esto no es recomendado Esta solución desplaza el trabajo a un hilo de fondo, por lo que cuando se reanuden las operaciones de sincronización, no tendrán un HttpContext
, etc. Esta solución completa la solicitud mientras todavía hay procesamiento por hacer. Esta solución no se comportará correctamente si el servidor se detiene / recicla en el momento equivocado.
Solo hay una solución adecuada: cambie CallSomeMethodWhichDoesAsyncOperations
.