Tengo que modificar el siguiente código. He dado una lista de tareas (el método httpClient.Run devuelve Task). Tengo que ejecutarlos y esperar hasta que todos estén listos. Más tarde, necesito recopilar todos los resultados y generar una respuesta.
var tasks = new Dictionary<string, Task<string>>(); tasks.Add("CODE1", service.RunTask("CODE1")); tasks.Add("CODE2", service.RunTask("CODE2")); tasks.Add("CODE3", service.RunTask("CODE3")); //... var result = await Task.WhenAll(tasks.Values); // how to get CODE (dictionary KEY) here // build response El problema anterior es que cuando obtenemos results , hemos perdido exactamente qué tarea se ejecutó. resultados es una matriz de cadenas, pero necesito, por ejemplo, KeyValuePair array . Necesitamos saber qué tarea (CÓDIGO) se ejecutó, para que podamos generar el resultado correctamente.
Puede usar async en un Select lambda para transformar KeyValuePair<T1, Task<T2> s en Task<KeyValuePair<T1, T2>> s.
var resultTasks = tasks.Select(async pair => KeyValuePair.Create(pair.Key, await pair.Value)); IReadOnlyCollection<KeyValuePair<string, string>> results = await Task.WhenAll(resultTasks);Algo como esto debería hacerlo. Esto está escrito asumiendo que primero haces la llamada Task.WhenAll() . De lo contrario, bloqueará el hilo cuando comience a enumerar resultados con resultsWithKeys .
await Task.WhenAll(tasks.Values()); var resultsWithKeys = tasks.Select( x => new { Key = x.Key, Result = x.Value.Result }); foreach (var result in resultsWithKeys) Console.WriteLine($"{result.Key} - {result.Result.SomeValue}");Dictionary<string, Task<string>> contiene tareas que no propagan la clave como parte de su Result . Si prefiere tener tareas que incluyan la clave en su resultado, deberá crear un nuevo diccionario y llenarlo con nuevas tareas que envuelvan las tareas existentes. El TResult de estas nuevas tareas puede ser una estructura de su elección, por ejemplo, KeyValuePair<string, string> . A continuación se muestra un método de extensión WithKeys que permite crear fácilmente el nuevo diccionario con las nuevas tareas:
public static Dictionary<TKey, Task<KeyValuePair<TKey, TValue>>> WithKeys<TKey, TValue>( this Dictionary<TKey, Task<TValue>> source) { return source.ToDictionary(e => e.Key, async e => KeyValuePair.Create(e.Key, await e.Value.ConfigureAwait(false)), source.Comparer); }Ejemplo de uso:
KeyValuePair<string, string>[] result = await Task.WhenAll(tasks.WithKeys().Values);