tag route page net asp asp.net async-await

asp.net - page - asp route tag helper



¿Qué eventos del ciclo de vida de ASP.NET pueden ser asíncronos? (2)

He escrito un control ASP.NET personalizado y lo actualicé para tener un controlador de eventos asíncrono Load. Ahora estoy recibiendo este error:

No se puede iniciar una operación asíncrona 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 como <% @ Page Async = "true"%>.

La página ya tiene la etiqueta <%@ Page Async="true" %> ya. Así que supongo que los controles no pueden tener controladores de eventos de carga asíncrona.

¿Dónde puedo encontrar una lista completa de eventos en el ciclo de vida de los formularios web de ASP.NET que pueden ser asíncronos?


Damian Edwards del equipo de ASP.NET dio esta respuesta:

Los controladores de eventos de Async void en formularios web solo son compatibles con ciertos eventos, como se ha encontrado, pero en realidad solo están destinados a tareas simplistas. Recomendamos utilizar PageAsyncTask para cualquier trabajo asíncrono de cualquier complejidad real.

Levi Broderick del equipo de ASP.NET dio esta respuesta:

Los eventos asíncronos en aplicaciones web son bestias intrínsecamente extrañas. Async void está pensado para un modelo de programación de fuego y olvido. Esto funciona en las aplicaciones de la interfaz de usuario de Windows, ya que la aplicación se mantiene hasta que el sistema operativo la mata, por lo que siempre que se ejecute la devolución de llamada asíncrona, se garantiza que existe un subproceso de la interfaz de usuario con la que puede interactuar. En aplicaciones web, este modelo se desmorona ya que las solicitudes son, por definición, transitorias. Si la devolución de llamada asíncrona se ejecuta después de que la solicitud haya finalizado, no hay garantía de que las estructuras de datos con las que necesita interactuar la devolución de llamada todavía estén en buen estado. Por lo tanto, por qué disparar y olvidar (y un vacío asíncrono) es inherentemente una mala idea en las aplicaciones web.

Dicho esto, hacemos gimnasia loca para tratar de hacer que cosas muy simples como Page_Ladad funcione, pero el código para admitir esto es extremadamente complicado y no está bien probado para nada más allá de los escenarios básicos. Así que si necesitas confiabilidad me quedo con RegisterAsyncTask.

Así que creo que la respuesta a mi pregunta es: "Esa es la pregunta incorrecta".

La pregunta correcta sería "¿Cómo debo ser asíncrono en mi aplicación de formularios web ASP.NET?" Y la respuesta es insertar este fragmento de código dentro del archivo de código subyacente de aspx:

this.RegisterAsyncTask(new PageAsyncTask(async cancellationToken => { var result = await SomeOperationAsync(cancellationToken); // do something with result. }));

Este mismo truco funciona dentro de los controles personalizados de ASP.NET, solo use this.Page.RegisterAsyncTask en this.Page.RegisterAsyncTask lugar.


Esta página explica cómo el manejo de eventos del ciclo de vida en páginas asíncronas difiere de las páginas sincrónicas en ASP.NET 2.0 (la Figura 2 es especialmente útil):

Código malvado: Páginas asíncronas en ASP.NET 2.0

También puede encontrar esta pregunta de uso SO (habla del mismo mensaje de error):

Palabra clave asíncrona y elección del TaskScheduler