Y at-il un moyen dans la nouvelle bibliothèque async dotnet 4.5 pour définir un délai d'arrêt sur la `` méthode. Je veux aller chercher plusieurs sources et arrêter après dire 5 secondes et sauter les sources qui n'étaient pas terminées.
Réponses
Trop de publicités?Je pense plus clair, plus robuste option qui a également fait la gestion des exceptions droit serait d'utiliser Task.WhenAny
sur chaque tâche en collaboration avec un délai d'attente de tâche, passer par toutes les tâches et filtrer le délai d'attente et await Task.WhenAll()
au lieu de Task.Result
pour rassembler tous les résultats.
Voici une complète solution de travail:
static async Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks, TimeSpan timeout)
{
var timeoutTask = Task.Delay(timeout).ContinueWith(_ => default(TResult));
var completedTasks =
(await Task.WhenAll(tasks.Select(task => Task.WhenAny(task, timeoutTask)))).
Where(task => task != timeoutTask);
return await Task.WhenAll(completedTasks);
}
Consultez les sections « Early Bailout » et « Task.Delay » de microsoft's Task-Based Asynchronous Pattern Overview.
- Sauvetage anticipé. Une opération représentée par t1 peut être regroupée dans un WhenAny avec une autre tâche t2, et nous pouvons attendre sur la tâche WhenAny. t2 pourrait représenter un délai d'arrêt, ou une annulation, ou un autre signal qui entraînera la tâche WhenAny à terminer avant t1 terminé.
Ce que vous décrivez semble être un très commun de la demande cependant je ne pouvais pas trouver n'importe où, un exemple de cela. Et j'ai beaucoup cherché... j'ai finalement créé le suivant:
TimeSpan timeout = TimeSpan.FromSeconds(5.0);
Task<Task>[] tasksOfTasks =
{
Task.WhenAny(SomeTaskAsync("a"), Task.Delay(timeout)),
Task.WhenAny(SomeTaskAsync("b"), Task.Delay(timeout)),
Task.WhenAny(SomeTaskAsync("c"), Task.Delay(timeout))
};
Task[] completedTasks = await Task.WhenAll(tasksOfTasks);
List<MyResult> = completedTasks.OfType<Task<MyResult>>().Select(task => task.Result).ToList();
Je suppose ici une méthode SomeTaskAsync que revient la Tâche<MyResult>.
Parmi les membres de completedTasks, seules les tâches de type MyResult sont nos propres tâches qui ont réussi à battre l'horloge. De la tâche.Retard retourne un type différent. Cela nécessite de faire des compromis sur le typage, mais tout fonctionne à merveille et très simple.
(Le tableau peut bien sûr être construit de manière dynamique à l'aide d'une requête + ToArray).
- Notez que cette mise en œuvre ne nécessite pas de SomeTaskAsync de recevoir un jeton d'annulation.
Je suis venu à la pièce suivante de code qui fait ce dont j'avais besoin:
Mon explication est dans mon blogpost: http://blog.bekijkhet.com/2012/03/c-async-examples-whenall-whenany.html