IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Task: Simplification possible ?


Sujet :

C#

  1. #1
    Membre éprouvé
    Homme Profil pro
    Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique
    Inscrit en
    Décembre 2014
    Messages
    449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 449
    Points : 991
    Points
    991
    Par défaut Task: Simplification possible ?
    Bonjour,

    Ca me tarabuste car je me dis que ça doit être simplifiable mais je cale, j'essaie de faire de l'async mais comme je débute...


    Cahier des charges, je lance une fonction quipeut prendre du temps, elle liste le contenu de répertoires surveillés, j'ai opté pour lancer des tâches en asynchrone pour gagner du temps (ce qui fonctionne bien avec ce code).

    J'ai besoin d'attendre le résultat de ces tâches afin de lancer un processus commun de traitement par la suite et d'affecter le contenu dans une liste de classe etc... Si je colle le résult dans la première boucle, même avec un await ça attend, j'ai mis un chrono, plus des affichages, on voit bien que c'est dans l'ordre. J'ai un peu tripatouiller dans tous les sens, sans pour autant trouver au final une syntaxe efficace mais plus simple, je suis sur d'avoir lu à un moment une autre façon de faire mais je ne retrouve plus mes sources (je ne parle pas de convertir en Task.Run directement mais plutot de ne pas passer par deux boucles)

    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
     
     
                var arrayTask = new Task<List<WatchedFile>>[listeDirs.Count];
     
                for (int i=0; i < listeDirs.Count; i++)
                {
                    string dir = listeDirs[i];
                    Task<List<WatchedFile>> t = new Task<List<WatchedFile>>(() => MakeListeDir(dir) );
     
                    arrayTask[i] = t;
                    t.Start();
     
                }
     
                for( int i =0; i < listeDirs.Count; i++ )
                {
     
                    arrayTask[i].Wait();
                    newListe[i].ListeFichiers = arrayTask[i].Result;
     
                }
    Désolé j'espère ne pas abuser.

    Merci.

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    je ne suis pas expert en task, mais j'ai cru comprendre que ce n'était pas forcément exécuté sur un autre thread, mais parfois ca se partage un seul thread
    essaye en démarrant des threads, puis en faisant des .join pour les attendre, là ca sera forcément tous en même temps (sachant que pour des accès disques prononcés (hors ssd) ce n'est pas toujours une bonne idée, il y a parfois un nombre de threads à ne pas dépasser)
    (le threadpool permet de limiter à n threads à la fois)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 760
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Je verrais bien quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var arrayTask = new Task<List<WatchedFile>>[listeDirs.Count];
     
    for (int i=0; i < listeDirs.Count; i++)
    {
       string dir = listeDirs[i];
       int currentIndex = i; // Indispensable ici.
       arrayTask[i] = Task.Run(() => newListe[currentIndex] = MakeListeDir(dir) );
    }
     
    Task.WaitAll(arrayTask);
    À noter qu'il est indispensable de copier l'index i pour une utilisation dans la closure. Sinon, il y a des problèmes en perspective ! (cf. closure et variable de boucle)

    Citation Envoyé par Pol63
    je ne suis pas expert en task, mais j'ai cru comprendre que ce n'était pas forcément exécuté sur un autre thread, mais parfois ça se partage un seul thread
    C'est vrai pour les tâches gérées via async/await, où le contexte d'exécution est par défaut le contexte du thread courant. Par exemple, dans le cas des winform, le contexte d'exécution est le thread graphique. Donc monothread.

    Sinon, sans précision particulière, les Task s'exécutent sur le contexte par défaut, qui utilise le pool de threads.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  4. #4
    Membre éprouvé
    Homme Profil pro
    Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique
    Inscrit en
    Décembre 2014
    Messages
    449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 449
    Points : 991
    Points
    991
    Par défaut
    Merci,

    J'avais noté pour l'index en effet car ç'a m'a rendu barge en fin de journée, sur un banal test pour lancer plusieurs tâches de durées différentes et de voir quelle solution permettait d'avoir vraiment les tâches séparées. Mais bêtement ça ne m'est pas venu à l'idée de faire un cliché de la valeur de i ce qui fait que je me prenais régulièrement un newListe[i]. Du coup je peux tout remettre en Task.run et je dirais "ouf!!". Puis le pire c'est que lorsque ça commence à partir en vrille à un moment donné tu ne trouves plus rien de bon, je moulinais.

    Merci beaucoup ! Passez une bonne journée !

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 760
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par daerlnaxe Voir le message
    J'avais noté pour l'index en effet car ç'a m'a rendu barge en fin de journée, sur un banal test pour lancer plusieurs tâches de durées différentes et de voir quelle solution permettait d'avoir vraiment les tâches séparées. Mais bêtement ça ne m'est pas venu à l'idée de faire un cliché de la valeur de i ce qui fait que je me prenais régulièrement un newListe[i]
    C'est certes un peu déroutant au début, mais c'est ce qui fait la force des closures : on capture des variables, et non la valeur des variables au moment où on crée la closure. La nuance est subtile mais implique un comportement qui n'est pas toujours évident à appréhender.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 17/07/2014, 08h32
  2. [XL-2007] simplification possible d'un programme sous VBA
    Par lps02 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 29/01/2012, 20h17
  3. Simplification possible ?
    Par Madfrix dans le forum Requêtes
    Réponses: 2
    Dernier message: 22/09/2011, 12h15
  4. Simplification de code possible?
    Par Jules24 dans le forum VB.NET
    Réponses: 3
    Dernier message: 25/06/2011, 20h20
  5. Réponses: 1
    Dernier message: 10/10/2008, 09h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo