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

VB.NET Discussion :

Multithreading : Limiter le nombre de threads actifs


Sujet :

VB.NET

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Points : 56
    Points
    56
    Par défaut Multithreading : Limiter le nombre de threads actifs
    Bonjour à tous, ma question est assez simple.

    Je souhaiterais savoir comment procéder pour limiter le nombre de threads actifs dans mon application. Mon code d'exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    For Each O as Object In ListeQuelconque(Of Object)
          Threading.Tasks.Task.Factory.StartNew(Sub() Bidon(O))
    Next
    Le problème étant que j'ai plusieurs milliers d'objets dans cette liste, et que cela me crée des milliers de threads quasi-instantanément. Je voudrais donc limiter au nombre de 5 les threads, par exemple, et pouvoir "attendre" la fin d'un thread pour en créer un nouveau et continuer ma boucle.

    A savoir que ma procédure Bidon() prend plusieurs secondes à s'effectuer (accès à internet etc) et c'est la raison pour laquelle je fais appel aux thread.

    Je vous remercie d'avance pour vos réponses et vos conseils.

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour. Je serais très étonné que cela crée des milliers de threads. Des milliers de tâches, oui, mais pas des milliers de threads.

    SI d'aventure je me trompais, System.Threading.ThreadPool.SetMaxThreads devrait faire l'affaire en limitant la concurrence dans tout le programme. Et pour ne limiter la concurrence que pour ce groupe de tâches on peut à la place créer une Taskfactory avec un TaskScheduler personnalisé, mais c'est plus fastidieux.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Points : 56
    Points
    56
    Par défaut
    Oui autant pour moi, j'ai utilisé des Task (j'avoue ne pas avoir encore trop saisi la différence avec les thread) seulement plus tard à la recherche d'une solution.
    Merci pour votre aide, je test SetMaxThreads et je met le sujet en résolu si ça fonctionne. Sinon je tenterai avec TaskScheduler.

  4. #4
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Inutile de modifier SetmaxThreads dans ce cas.

    Une tâche, c'est une opération à effectuer "dès que possible". Un thread, c'est un ouvrier pouvant exécuter des tâches. Un coeur (comme dans "processeur à 8 cores"), c'est un atelier dans lequel un ouvrier peut travailler.

    Il est donc normal qu'il y ait des milliers de tâches, ce qui ne pose aucun problème. Windows va ensuite embaucher quelques ouvriers (threads), les répartir dans les 4 à 8 ateliers (coeurs du processeur) et leur assigner des tâches de façon optimale. Inutile de s'en mêler.

    Et pour compléter l'analogie : quand une tâche sera bloquée parce qu'elle attend la réponse du serveur, Windows mettra l'ouvrier sur une nouvelle tâche, qui reprendra la première une fois les données reçues.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Points : 56
    Points
    56
    Par défaut
    Merci pour votre réponse imagée, c'est tout de suite plus clair. En revanche mon problème est toujours présent, car la raison qui me pousse a vouloir limiter le nombre de tâches simultanées, c'est pour une question de performance.

    En effet, ma méthode va chercher une image sur internet et la stocker dans une variable (ce qui utilise beaucoup de ressources, dans mes tests j'arrivais en quelques secondes à 2Go de RAM utilisée par mon application... Sans parler de la bande passante, même si c'est un peu moins gênant), et je tiens à éviter cela.

    Dans ce cas y a-t-il un moyen de palier à ce problème ?

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    A partir du Framework 4 tu as la classe Parallel : http://msdn.microsoft.com/fr-fr/libr...vs.100%29.aspx

  7. #7
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Ah ! En effet, c'est fâcheux, pour peu que la compression jpeg atteigne du 1:100 une connexion à 100Mbps remplira la mémoire à 10Gbps.

    Une façon simple de faire serait de limiter le nombre de threads. Le plus simple pour ça serait d'utiliser un nombre fixe de threads (nombre choisi en fonction de la mémoire) plutôt que des tâches avec des threads créés dynamiquement. Chaque thread piocherait dans une ConcurrentQueue une url à télécharger.

    Cela dit, si l'on connaît à l'avance la taille de l'image (est-ce le cas ?), il est possible de faire mieux, en mettant une tâche en pause en attendant que la mémoire se libère via GC.AddMemoryPressure (ou un truc de ce genre).

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Points : 56
    Points
    56
    Par défaut
    Merci pour toutes vos réponses. Je n'ai pas encore eu le temps de tout tester mais vous m'avez donné suffisamment d'éléments pour que je puisse trouver une solution.
    Bonne journée à vous

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

Discussions similaires

  1. Limiter le nombre de Threads
    Par sunp dans le forum Concurrence et multi-thread
    Réponses: 7
    Dernier message: 11/03/2008, 11h02
  2. Limite au nombre de Thread
    Par uriotcea dans le forum Threads & Processus
    Réponses: 7
    Dernier message: 21/12/2007, 14h34
  3. [MFC] Limitation du nombre de fichiers...
    Par chronos dans le forum MFC
    Réponses: 5
    Dernier message: 02/06/2004, 10h40
  4. Limiter le nombre d'enregistrement
    Par BXDSPORT dans le forum Bases de données
    Réponses: 2
    Dernier message: 22/04/2004, 16h26
  5. [débutant] Limitation du nombre d'enregistrement renvoyé
    Par tmcgrady dans le forum Langage SQL
    Réponses: 4
    Dernier message: 12/11/2003, 09h41

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