EntityFramework (6) y async (waitingForActivation)?

.net-4.5 async-await c# entity-framework entity-framework-6

Pregunta

He descargado EF6 (para usar async )

Así que escribí este método simple:

  public async Task<List<int>> MyasyncMethod()
      {
          var locations = await MyDumpEntities.AgeGroups.Select(f=>f.endYear).ToListAsync();
          return locations;
       }

   ...Later...


  DumpEntities1 MyDumpEntities = new DumpEntities1();
  var data = MyDumpEntities.AgeGroups.ToListAsync();
  MyasyncMethod().ContinueWith(s => { Response.Write("f"); });
  MyDumpEntities.Dispose();

Pero no veo nada en la pantalla y cuando inspecciono los data veo esto:

introduzca la descripción de la imagen aquí

ps esta es la firma ToListAsync introduzca la descripción de la imagen aquí

Qué me estoy perdiendo ?

Respuesta aceptada

Basándolo de los comentarios y la línea con la que tiene problemas:

var data = MyDumpEntities.AgeGroups.ToListAsync();

¿Cuál será data tipo de data ? Task<List<AgeGroup>> Eso es correcto, no List<AgeGroup> . Entonces, tienes que marcar la Page_Load como asíncrona (si es posible):

var data = MyDumpEntities.AgeGroups.ToListAsync();

O esperar la ejecución de alguna manera (continuación, bloqueo de espera).

Otra cosa (alguien más podría querer corregir eso si estoy equivocado), pero como está usando la continuación para la segunda llamada, tendría mucho cuidado de disponer el contexto fuera de la continuación. Puede resultar que disponga el contexto de forma preventiva. En este caso particular, no está utilizando el contexto en la continuación, pero parece sospechoso ...

Así que yo tampoco

var data = MyDumpEntities.AgeGroups.ToListAsync();

O simplemente usa async allí también

var data = MyDumpEntities.AgeGroups.ToListAsync();

y agregue Async="True" a la directiva de página


Respuesta popular

Otros han señalado que la solución correcta es usar await , pero no veo una buena explicación de por qué .

Hay dos razones por las que el código original es incorrecto. Primero, está usando ContinueWith sin capturar el contexto en una aplicación ASP.NET, por lo que la continuación (la llamada Response.Write ) no tiene un contexto de solicitud y, por lo tanto, no tiene una respuesta para escribir.

await se encarga de esto, capturando el contexto antes de la await y usándolo para reanudar el resto del método; en este caso, capturará un AspNetSynchronizationContext representa la solicitud / respuesta actual.

La otra razón es que el código asíncrono se ejecutará simultáneamente. Entonces, MyasyncMethod comenzará a ejecutarse, alcanzará su await y devolverá una tarea incompleta a Page_Load . Page_Load luego adjunta una continuación a esa tarea y continúa ejecutándose , eliminando el contexto. Por lo tanto, el contexto puede eliminarse mientras la solicitud ToListAsync aún se está ejecutando.

await también corrige esto para usted porque va a "hacer una pausa" el Page_Load método hasta MyasyncMethod es completa.

Como nota final, también debe considerar estos puntos al usar async en ASP.NET:

  1. Debes apuntar a .NET 4.5. No utilice Microsoft.Bcl.Async .
  2. Debe establecer targetFramework en 4.5 o establecer UseTaskFriendlySynchronizationContext en true.
  3. (Solo para WebForms) Establezca Page.Async en true.
  4. Considere utilizar RegisterAsyncTask lugar de await . Normalmente prefiero await porque los diferentes métodos tienen más separación de preocupaciones, pero el equipo de ASP.NET prefiere RegisterAsyncTask porque hay un único punto de "sincronización" después de PreRender donde el tiempo de ejecución espera a que se completen todas las operaciones. Vea este artículo para saber cómo usar RegisterAsyncTask .
  5. Construye tus propios tiempos de espera de solicitud. Las solicitudes asíncronas de ASP.NET no utilizan automáticamente los tiempos de espera normales que están incorporados a las solicitudes sincrónicas de ASP.NET. Hay dos opciones:
    • Utilice el token de cancelación HttpRequest.TimedOut .
    • (Solo para WebForms / RegisterAsyncTask ) Puede agregar un tiempo de espera asíncrono configurando Page.AsyncTimeout y haciendo que su método async tome un CancellationToken .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué