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

310
Vistas
Evite verificar la condición dos veces al asignar desde la tarea esperada con Task.WhenAll()

¿Hay una mejor manera de escribir este código asincrónico (por ejemplo, para que no tenga que repetir if (myCondition) dos veces)? Quiero evitar usar Task.Run aquí.

 var tasks = new List<Task>(); Task<String> t1 = null; Task<String> t2 = null; if (myCondition) { t1 = getAsync(); tasks.Add(t1); } if (myOtherCondition) { t2 = getAsync2(); tasks.Add(t2); } await Task.WhenAll(tasks) if (myCondition) { result.foo = await t1; } if (myOtherCondition) { result.bar = await t2; }
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Sin saber realmente cuáles son sus condiciones, creo que normalmente movería esa verificación dentro del método que realmente se relaciona con obtener foo o bar. Parece un caso en el que tu único método hace más de lo que se supone que debe hacer.

Un enfoque diferente:

 var fooTask = GetFoo(); var barTask = GetBar(); await Task.WhenAll(new [] { fooTask, barTask }); result.foo = (await fooTask) ?? result.foo; result.bar = (await barTask) ?? result.bar; // ... async Task<string> GetFoo() { if (!myCondition) { return Task.FromResult((string)null); } return await DoHeavyWorkFoo(); } async Task<string> GetBar() { if (!myOtherCondition) { return Task.FromResult((string)null); } return await DoHeavyWorkBar(); }
over 4 years ago · Santiago Trujillo Denunciar

0

Una forma de hacerlo es tener dos listas, una lista de tareas y una lista de acciones. Las acciones se invocarán secuencialmente después de la finalización de todas las tareas y asignarán las propiedades del objeto de result . Ejemplo:

 var tasks = new List<Task>(); var actions = new List<Action>(); var result = new MyClass(); if (myCondition) { var task = getAsync(); tasks.Add(task); actions.Add(() => result.Foo = task.Result); } if (myOtherCondition) { var task = getAsync2(); tasks.Add(task); actions.Add(() => result.Bar = task.Result); } await Task.WhenAll(tasks); actions.ForEach(action => action());

De esta forma, no necesita almacenar cada Task en una variable separada, porque cada expresión lambda captura la variable de la task en el ámbito interno del bloque if . Cuando se invoca la Action , la task se completará y, por lo tanto, la task.Result no se bloqueará.


Solo por diversión : si quiere ser elegante, puede encapsular esta funcionalidad de "inicialización de objetos paralelos" en una clase ObjectInitializer , que invocaría todos los métodos asincrónicos al mismo tiempo, y luego crearía un nuevo objeto y asignaría el valor de cada una de sus propiedades. secuencialmente:

 public class ObjectInitializer<TObject> where TObject : new() { private readonly List<Func<object, Task<Action<TObject>>>> _functions = new(); public void Add<TProperty>(Func<object, Task<TProperty>> valueGetter, Action<TObject, TProperty> propertySetter) { _functions.Add(async arg => { TProperty value = await valueGetter(arg); return instance => propertySetter(instance, value); }); } public async Task<TObject> Run(object arg = null) { var getterTasks = _functions.Select(f => f(arg)); Action<TObject>[] setters = await Task.WhenAll(getterTasks); TObject instance = new(); Array.ForEach(setters, f => f(instance)); return instance; } }

Ejemplo de uso:

 var initializer = new ObjectInitializer<MyClass>(); if (myFooCondition) initializer.Add(_ => GetFooAsync(), (x, v) => x.Foo = v); if (myBarCondition) initializer.Add(_ => GetBarAsync(), (x, v) => x.Bar = v); MyClass result = await initializer.Run();
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