TPL... Tasks... etc.

21 views
Skip to first unread message

Florian

unread,
Aug 8, 2012, 4:04:28 AM8/8/12
to paris...@googlegroups.com
Bonjour à tous, 

je me permets de poser une petite question... Je voulais savoir quel était le moyen "conseillé" pour récupérer la première tâche terminée qui retourne un résultat particulier attendu (true pour faire simple) :

aujourd'hui j'ai ça : 

Task<bool> t0 = Task.Factory.StartNew<bool>(() => Find(paramA, paramB));
Task<bool> t1 = Task.Factory.StartNew<bool>(() => Find(paramC, paramD));
Task<bool> t2 = Task.Factory.StartNew<bool>(() => Find(paramE, paramF));
Task<bool> t3 = Task.Factory.StartNew<bool>(() => Find(paramG, paramH));

Task.WaitAll(new Task[] { t0, t1, t2, t3, t4 });
return t0.Result | t1.Result | t2.Result | t3.Result | t4.Result;
mais je voudrais que dès qu'une tâche renvoie true, alors je renvoie directement true et je n'attend pas que toutes les tâches soit terminées.
Il y a un moyen de faire ça simplement ?
Merci pour vos suggestions
Question subsidiaires : Une fois qu'une tâche a renvoyé true, est-ce qu'il vaut mieux annuler l'exécution des autres  tâches en cours ou bien les laisser terminer leurs exécutions normalement.

Mathias Kluba

unread,
Aug 8, 2012, 4:17:36 AM8/8/12
to paris...@googlegroups.com
Hello,

Pourquoi ne pas attendre un seul "WaitHandle" (genre ManualResetEvent) partagé par les tâches?
Le premier qui fait "waitHandle.Set()" va réveiller ton waitHandle (waitHandle.WaitOne())

Perso, je ne vois pas d'inconvénient à annuler une tâche...

my2cents

--
Mathias Kluba
Twitter: @mathiaskluba
Blog: http://grozeille.com

Bruno Baia

unread,
Aug 8, 2012, 4:24:46 AM8/8/12
to paris...@googlegroups.com
Salut,

As tu essayé Task.WaitAny ?


- Bruno

Florian Nouri

unread,
Aug 8, 2012, 4:35:13 AM8/8/12
to paris...@googlegroups.com
En fait ce que j'essaie d'avoir c'est un truc du genre :

Task[] tasks = new Task[]{t0,t1,t2,t3,t4};
Task<bool> t = Task.WhenAny(tasks, t => t.Result = true); // Condition
qui dit quand une tâche est terminé et que le résultat est True



2012/8/8 Bruno Baia <brb...@gmail.com>:

Geoffrey DANIEL

unread,
Aug 8, 2012, 4:37:37 AM8/8/12
to paris...@googlegroups.com
Si aucun ne renvoie true qu'attends tu comme comportement ?

2012/8/8 Florian Nouri <floria...@gmail.com>



--
Geoffrey DANIEL

Florian Nouri

unread,
Aug 8, 2012, 4:41:49 AM8/8/12
to paris...@googlegroups.com
que ça renvoie false
en gros je veux la même chose que ça :

Task.WaitAll(new Task[] { t0, t1, t2, t3, t4 });
return t0.Result | t1.Result | t2.Result | t3.Result | t4.Result;

mais que dès qu'une tâche renvoie true, on arrête de faire le wait.


2012/8/8 Geoffrey DANIEL <neuro...@gmail.com>:

Geoffrey DANIEL

unread,
Aug 8, 2012, 6:17:36 AM8/8/12
to paris...@googlegroups.com
Bon c'est un truc totallement a l'arrache et qui pourrait surement etre ameliore 100 fois mais si ca peut te depanner temporairement voila ce que je viens de faire rapidement

using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            var array = new Task<bool>[]
            {
                Task.Factory.StartNew<bool>(() => TestCountBool(10, false)),
                Task.Factory.StartNew<bool>(() => TestCountBool(10, false)),
                Task.Factory.StartNew<bool>(() => TestCountBool(12, true)),
                Task.Factory.StartNew<bool>(() => TestCountBool(10, false))
            };

            var task = array.WaitAnyWithCondition(t => t.Result == true);

        }
        
        private static bool TestCountBool(int nbIteration, bool result)
        {
            while (nbIteration-- > 0)
                Task.Delay(500);

            return result;
        }
    }

    public static class TaskExtensions
    {
        public static Task<T> WaitAnyWithCondition<T>(this Task<T>[] tasks, Predicate<Task<T>> predicate)
        {
            var list = tasks.ToList();

            while (list.Count > 0)
            {
                var id = Task.WaitAny(list.ToArray());
                
                if (list.Count == 1 || predicate(list[id]))
                    return list[id];
                
                list.RemoveAt(id);
            }

            return default(Task<T>);
        }
    }
}


2012/8/8 Florian Nouri <floria...@gmail.com>



--
Geoffrey DANIEL

Florian Nouri

unread,
Aug 8, 2012, 6:20:44 AM8/8/12
to paris...@googlegroups.com
WOUAOW Sympa ! Je teste ça !
Merci en tout cas !

2012/8/8 Geoffrey DANIEL <neuro...@gmail.com>:

Florian Nouri

unread,
Aug 8, 2012, 7:24:06 AM8/8/12
to paris...@googlegroups.com
ça marche nickel ! Merci !

2012/8/8 Florian Nouri <floria...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages