Demande d'aide sur une application multi-thread [Résolu]

Signaler
-
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
-
Bonjour tout le monde,
Afin d'amélioré mon programme je compte le faire passer en multithread.

J'ai donc essayé un petit code tout bête.
Il s'agit de ce dernier.

Public Sub Launch()

Dim delegue(1) As ThreadStart
Dim monThread(1) As Thread
For ligne = 0 To 1
Select Case ligne
Case Is = 0

delegue(ligne) = New ThreadStart(AddressOf affichage) 'je lance sub affichage

Case Is = 1
delegue(ligne) = New ThreadStart(AddressOf affichage2) 'je lance sub affichage2

End Select

monThread(ligne) = New Thread(delegue(ligne))
monThread(ligne).Start()
monThread(ligne).Join()


Next

End sub


Tout marche, je suis happy.

En revanche, je dois aussi utilisé des tableaux de structure, décrémenter des tableaux pour en incrémenter d'autres,...
Je voulais donc trouver un moyen pour que plusieurs thread puissent utilisé des "copies" d'un même bout de code.

Si je suis dans le faux, ne vous gêner pas pour me le dire surtout.


Il me semble qu'utilisé une classe permettrait d'avoir un code générique que je pourrais instancié sans problème.
Seulement, je ne sais pas comment retourner les informations vers le code (ou thread) appelant le code de la classe.

Aussi, je suis preneur de toute solution.

Merci par avance.

10 réponses


Salut,

Voici un petit exemple qui permet de passer un objet au thread en paramètre de sa méthode Start. Ici, je passe une structure mais peux passer ce que tu veux, même des collections de classes différentes ou autre.

Option Strict On
Public Class Form1
    'délégué
    Private Delegate Sub MonDelegue(ByVal Valeur As Integer)

    'structure bidon
    Structure MaStructure
        Public d As Integer
    End Structure

    'générateur aléatoire
    Dim rd As New Random

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim t(1) As Threading.Thread
        t(0) = New Threading.Thread(AddressOf ThreadJob)
        t(1) = New Threading.Thread(AddressOf ThreadJob)

        'passage d'instances de structures en paramètre de Start
        t(1).Start(New MaStructure With {.d = 3})
        t(0).Start(New MaStructure With {.d = 6})
    End Sub

    Private Sub ThreadJob(ByVal obj As Object)
        'cast de l'objet vers le type MaStructure
        'on a maintenant l'objet passé au thread
        Dim struct As MaStructure = DirectCast(obj, MaStructure)
        Do
            'simulation d'un temps de calcul terriblement ennuyeux (avec temps aléatoire)
            Threading.Thread.Sleep(rd.Next(1000, 3000))
            'renvoi d'une valeur de l'instance de la structure qui a été passée au thread vers le thread appelant
            SubJob(struct.d)
        Loop
    End Sub

    Private Sub SubJob(ByVal MaValeur As Integer)
        'gestion des opérations inter threads
        If Me.InvokeRequired Then
            Me.Invoke(New MonDelegue(AddressOf SubJob), MaValeur)
        Else
            'affichage du résultat
            Me.Text = MaValeur.ToString
        End If
    End Sub
End Class

Bonjour,
Tu as aussi le BackgroundWorker et même un exemple chez MSDN.


Cordialement


CF2i - Guadeloupe
Ingénierie Informatique
Ok, je vais regardé ça de suite.
Juste pour savoir, mon idée de départ est bonne ou mauvaise ?

Oui, concernant la fluidité d'affichage etc, par contre il faut gérer les threads et franchement même moi je "m'en mêle les pinceaux"


Cordialement


CF2i - Guadeloupe
Ingénierie Informatique
Mais le composant BackgroundWorker est plus lent que le multithread lui-même selon certain.

Pour ma part, c'est le composant BackgroundWorker qui me rend fou, moi et la doc msdn.

Mon problème le plus ennuyant est que les 3/4 de mon programme aura la même vitesse (ou presque) en multithread puisque je gère beaucoup de tableaux lié entre eux.

L'utilisation se fait (à chose près) comme ça:
Public Class Form1
    Dim Worker As System.ComponentModel.BackgroundWorker

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i As Integer = 1 To 20 'il démarre 20 BackgroundWorkers
            Worker = New System.ComponentModel.BackgroundWorker
            AddHandler Worker.DoWork, AddressOf Worker_DoWork
            Worker.WorkerReportsProgress = True
            Worker.WorkerSupportsCancellation = True
            Worker.RunWorkerAsync()
        Next
    End Sub

    Private Sub Worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
        'Tâches à acomplir
    End Sub

End Class


Cordialement


CF2i - Guadeloupe
Ingénierie Informatique
Merci à vous deux.
Je vais essayé les 2 méthodes tout de suite.

En effet, les deux méthodes marchent pour moi.
Merci encore de votre aide et désolé du retard
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
1
Bonjour,

Je déterre ce topic juste pour savoir comment, une fois créé, on arrête ces "BackgroundWorker"?
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
226
Bonjour,
Tu as "bien sûr" lu le point 8 du lien vers MSDN donné au-dessus par acive le 5 juin 2013 à 13:38 ?
Alors ?