Hello tout le monde,

Aimant beaucoup m'intéresser au parallélisme et asynchronisme, j'ai lu et relu le sujet sur le site qui parle des pools de thread et qui est fort intéressant.

par pur intérêt à un moment, après avoir bossé avec sur mon programme et observé des réactions assez étranges en mesurant les temps d'éxécution... J'ai à un moment poussé le vice à demander un travail parallèle sur tous les fichiers contenus dans un programme, avec un travail simple.. et au lieu de me faire baisser le temps de travail, celui ci augmentait de temps en temps. Sur ces temps d'éxécutions quand j'ai simulé ce travail sur l'équivalent d'un fort nombre de fichiers sur une dizaine de dossier (qui eux mêmes bossaient sur différentes tâches) , j'ai observé ponctuellement que ça montait, j'ai mis en place un mode de calcul de temps moyen... et c'était moins intéressant.. je me suis donc mis de coté un tout petit algorithme encore plus simple et c'est là que j'ai percuté que le nombre de tâches était limité sur mon proc à 9 (si j'ai bien lu) en parallèle. (Il ne me semble pas que c'était abordé dans le tutoriel), après quoi c'est temporairement bloquant si j'ai bien fait attention, avant de relancer un autre paquet... Ce qui fait qu'au final les mesures en temps sont assez impressionnantes.
J'ai testé sous plusieurs formes donc le parallel.foreach (qui amène pas grand chose si ce n'est que ça évite d'écrire une méthode), et finalement j'ai tenté le mix, dont je ne comprenais pas l'intérêt en fait au prime abord... entre task.run et async.

et bref je voulais en faire profiter si certains ne s'étaient jamais posé la question puis aussi avoir confirmation, peut être que j'ai loupé un truc.

Donc premiere version (attention faut avoir ~27s à perdre - du moins sur mon proc , alors que ça devrait être 5s)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp2
{
    class Program
    {
        static string Foo()
        {
            for (int i = 1; i < 6; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(i);
 
                // await Task.Delay(1000);
            }
            Console.WriteLine("délais terminé");
            return "Marsupial";
        }
 
          static void Main(string[] args)
        {
            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
 
            List<string> mammouth = new List<string>();
 
            // tâche normale
            Task[] arrTask = new Task[100];
 
            for (int i = 0; i < 100; i++)
            {
                //  tâche normale
                var res = Task.Run(() => mammouth.Add(Foo()));
 
                arrTask[i] = res;
            }
 
            Console.WriteLine("Fini");
 
            Task.WaitAll(arrTask);
            foreach (string test in mammouth)
            {
                Console.WriteLine(test);
            }
            Console.WriteLine(sw2.ElapsedMilliseconds);
            Console.Read();
 
 
        }
    }
}
Et donc une version mixant qui est proche des 5s... 5 272ms:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp2
{
    class Program
    {
        static string Foo()
        {
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(i);
 
                // await Task.Delay(1000);
            }
            Console.WriteLine("délais terminé");
            return "Marsupial";
        }
 
        static async Task<string> AsyncFoo()
        {
            for (int i = 1; i < 6; i++)
            {
                await Task.Delay(1000);
                Console.WriteLine(i);
 
                // await Task.Delay(1000);
            }
            Console.WriteLine("délais terminé");
            return "Marsupial";
        }
 
 
        static void Main(string[] args)
        {
            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
 
            List<string> mammouth = new List<string>();
 
            // tâche normale
            Task[] arrTask = new Task[100];
 
            for (int i = 0; i < 100; i++)
            {
                //  tâche normale
                var res = Task.Run(async () => mammouth.Add(await AsyncFoo()));
 
                arrTask[i] = res;
            }
 
            Console.WriteLine("Fini");
 
            Task.WaitAll(arrTask);
            foreach (string test in mammouth)
            {
                Console.WriteLine(test);
            }
            Console.WriteLine(sw2.ElapsedMilliseconds);
            Console.Read();
 
 
        }
    }
}

Bon faites pas gaffe aux noms, c'est quand je n'ai pas envie de me casser la tête à en chercher un.

Je trouve l'exemple assez frappant (pas moi), et personnellement ça m'a vraiment fait réfléchir car avant je voyais pas trop l'intérêt, du moins dans le cadre de ce que je faisais, du "pourquoi mixer" ....

Bien sur sous réserve que je n'ai pas loupé quelque chose, le thread.sleep par exemple comparé au task.delay, ça agit très différemment.