Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

90
Vistas
Task.Factory.StartNew con asíncrono lambda y Task.WaitAll

Estoy tratando de usar Task.WaitAll en una lista de tareas. La cuestión es que las tareas son una lambda asíncrona que rompe Tasks.WaitAll ya que nunca espera.

Aquí hay un bloque de código de ejemplo:

 List<Task> tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(async () => { using (dbContext = new DatabaseContext()) { var records = await dbContext.Where(r => r.Id = 100).ToListAsync(); //do long cpu process here... } } Task.WaitAll(tasks); //do more stuff here

Esto no espera debido a la lambda asíncrona. Entonces, ¿cómo se supone que debo esperar las operaciones de E/S en mi lambda?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Task.Factory.StartNew no reconoce los delegados async , ya que no hay una sobrecarga que acepte una función que devuelve una Task .

Esta y otras razones (ver StartNew es peligroso ) es la razón por la que debería usar Task.Run aquí:

 tasks.Add(Task.Run(async () => ...
over 4 years ago · Santiago Trujillo Denunciar

0

Esto no espera debido a la lambda asíncrona. Entonces, ¿cómo se supone que debo esperar las operaciones de E/S en mi lambda?

El motivo por el que Task.WaitAll no espera a que finalice el trabajo de E/S presentado por su lambda asíncrona es porque Task.Factory.StartNew en realidad devuelve una Task<Task> . Dado que su lista es List<Task> (y Task<T> se deriva de Task ), espera en la tarea externa iniciada por StartNew , mientras ignora la interna creada por async lambda. Es por eso que dicen que Task.Factory.StartNew es peligroso con respecto a async.

¿Cómo pudiste arreglar esto? Podría llamar explícitamente a Task<Task>.Unwrap() para obtener la tarea interna:

 List<Task> tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(async () => { using (dbContext = new DatabaseContext()) { var records = await dbContext.Where(r => r.Id = 100).ToListAsync(); //do long cpu process here... } }).Unwrap());

O como dijeron otros, podrías llamar a Task.Run en su lugar:

 tasks.Add(Task.Run(async () => /* lambda */);

Además, dado que desea hacer las cosas bien, querrá usar Task.WhenAll , por qué se puede esperar de forma asíncrona, en lugar de Task.WaitAll que bloquea de forma síncrona:

 await Task.WhenAll(tasks);
over 4 years ago · Santiago Trujillo Denunciar

0

Puedes hacer esto.

 void Something() { List<Task> tasks = new List<Task>(); tasks.Add(ReadAsync()); Task.WaitAll(tasks.ToArray()); } async Task ReadAsync() { using (dbContext = new DatabaseContext()) { var records = await dbContext.Where(r => r.Id = 100).ToListAsync(); //do long cpu process here... } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda