c# - español - net core async controller
¿Cómo manejo las operaciones asíncronas en Startup.Configure? (3)
El código de ejemplo en el blog al que se vinculó solo usaba sync-over-async para llenar una base de datos con datos de ejemplo; esa llamada no existiría en una aplicación de producción.
Primero, diría que si realmente necesita
Configure
para ser asíncrono, entonces debe plantear un problema con el equipo ASP.NET para que esté en su radar.
No sería demasiado difícil para ellos agregar soporte para
ConfigureAsync
en este momento (es decir, antes del lanzamiento).
En segundo lugar, tiene un par de enfoques para el problema.
Puede usar
task.Wait
(o mejor aún,
task.GetAwaiter().GetResult()
, que evita el contenedor
AggregateException
si se produce un error).
O bien, puede almacenar en caché la
tarea en
lugar del
resultado
de la tarea (que funciona si
IMemoryCache
es más un diccionario que una cosa extraña de serialización en matriz binaria en memoria: lo estoy mirando, versiones anteriores de ASP.NET).
Si esto se considera una práctica aceptable, ¿qué, si es que hay alguno, manejo de errores necesito?
El uso de
GetAwaiter().GetResult()
provocaría que la excepción (si la hubiera) se propague fuera de
Configure
.
Sin embargo, no estoy seguro de cómo respondería ASP.NET si fallara la
configuración de
la aplicación.
No he proporcionado ningún mecanismo para cancelar la operación asincrónica.
No estoy seguro de cómo puede "cancelar" la configuración de una aplicación , por lo que no me preocuparía por esa parte.
En mi aplicación ASP.NET 5, quiero cargar algunos datos de Azure en un caché dentro de mi método Startup.Configure. El SDK de Azure expone métodos asíncronos exclusivamente. Por lo general, la llamada a un método asincrónico se realiza a través de wait dentro de un método asincrónico, como este:
public async Task Configure(IApplicationBuilder app, IMemoryCache cache)
{
Data dataToCache = await DataSource.LoadDataAsync();
cache.Set("somekey", dataToCache);
// remainder of Configure method omitted for clarity
}
Sin embargo, ASP.NET 5 requiere que el método Configure devuelva nulo. Podría usar un método de vacío asíncrono, pero entiendo que los métodos de vacío asíncrono solo se deben usar para controladores de eventos (según https://msdn.microsoft.com/en-us/magazine/jj991977.aspx entre muchos otros )
Estaba pensando que una mejor manera de hacer esto sería llamar a la función asincrónica sin esperar, llamar a Wait en la tarea devuelta, luego almacenar en caché los resultados a través de la propiedad Task.Results, así:
public void Configure(IApplicationBuilder app, IMemoryCache cache)
{
Task<Data> loadDataTask = DataSource.LoadDataAsync();
loadDataTask.Wait();
cache.Set("somekey", loadDataTask.Result);
// remainder of Configure method omitted for clarity
}
Stephen Walther utilizó un enfoque similar en una publicación de blog a principios de este año. Sin embargo, no está claro en esa publicación si esto se considera una práctica aceptable. ¿Lo es?
Si esto se considera una práctica aceptable, ¿qué, si es que hay alguno, manejo de errores necesito? Tengo entendido que Task.Wait () volverá a lanzar cualquier excepción lanzada por la operación asincrónica y no he proporcionado ningún mecanismo para cancelar la operación asincrónica. ¿Es simplemente llamar a Task.Wait () suficiente?
Las respuestas aquí no siempre funcionan correctamente si su código asincrónico realiza más llamadas asincrónicas, especialmente si son devoluciones de llamada, entonces puede encontrar los puntos muertos de código.
Esto me ha
Nito.AsyncEx
en numerosas ocasiones y he usado el
Nito.AsyncEx
con gran efecto.
using Nito.AsyncEx;
AsyncContext.Run(async () => { await myThing.DoAsyncTask(); });
Puede hacer un trabajo asincrónico, pero el método es sincrónico y no puede cambiarlo. Esto significa que debe esperar sincrónicamente a que se completen las llamadas asíncronas.
No desea regresar de un método de Inicio si el inicio aún no ha terminado, ¿verdad? Su solución parece estar bien.
En cuanto al manejo de excepciones: si hay una tarea sin la cual su aplicación no puede ejecutarse correctamente, debe dejar que el método de Inicio falle (consulte Fail-fast ). Si no es algo crítico, incluiría la parte relevante en un bloque try catch y simplemente registraría el problema para una inspección posterior.