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 :

Modifier un controle textB en threadsafe


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut Modifier un controle textB en threadsafe
    Bonjour


    j'essai de modifier un textbox ou un label à partir de thread, voici le code essayé

    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
    Imports System.Threading
    Imports System.IO
    Imports System.Text
    Imports System.Net.NetworkInformation
    Public Class Form1
     
     
        Delegate Sub OneArgSub(ByVal Msg As String)
        Dim deleg As OneArgSub
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'Créer un nouveau thread et définir sont point de départ
            Dim t As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            Dim t1 As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            Dim t2 As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            'Exécute le nouveau thread
            t.Start()
            t1.Start()
            t2.Start()
        End Sub
     
        Sub DotheTask()
            Dim i As Integer
            For i = 1 To 10
                'Monte que le thread a reçu les bonnes valeurs.
                'Console.WriteLine("Msg # {0} du thread principal avec la valeur", i.ToString)
                deleg = New OneArgSub(AddressOf LblEnvok)
                SyncLock deleg
                    deleg.Invoke("Msg # " & i & " du thread principal avec la valeur")
                End SyncLock
                Threading.Thread.Sleep(200)
            Next
        End Sub
     
        Sub LblEnvok(ByVal msg As String)
            Label1.Text = msg.ToString
        End Sub
    End Class
    et le message d'erreur suivant apparait

    L'exception System.InvalidOperationException n'a pas été gérée
    Message=Opération inter-threads non valide*: le contrôle 'Label1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
    Source=System.Windows.Forms
    StackTrace:
    à System.Windows.Forms.Control.get_Handle()
    à System.Windows.Forms.Control.set_WindowText(String value)
    à System.Windows.Forms.Control.set_Text(String value)
    à System.Windows.Forms.Label.set_Text(String value)
    à thread.Form1.LblEnvok(String msg) dans C:\Users\Mario\documents\visual studio 2010\Projects\thread1\thread1\Form1.vb:ligne 36
    à thread.Form1.DotheTask() dans C:\Users\Mario\documents\visual studio 2010\Projects\thread1\thread1\Form1.vb:ligne 29
    à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    à System.Threading.ExecutionContext.runTryCode(Object userData)
    à System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
    à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
    à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Threading.ThreadHelper.ThreadStart()
    InnerException:
    merci de votre aide

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    thread+delegue
    ou backgroundworker qui a des évènements ramenés sur le thread principal

    et le mot thread safe désigne autre chose que le problème d'inter thread que tu as ici
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    ok, donc comment je fait pour résoudre mon problème d'inter-thread ?

    suis-je sur la bonne piste avec un délégué?

    merci

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    deleg.invoke invoke le délégué sur le thread actuel
    or il faut dans ton cas dire ç un controle d'invoker le délégué sur son thread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    label1.invoke(deleg,msg)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    Un grand merci pol63 pour ton aide j'avance tranquillement alors encore merci d'être patient

    maintenant j'ai un message suivant

    L'exception System.StackOverflowException n'a pas été gérée
    InnerException:
    comme je débute dans le multi-threading je retourne à mes bouquins pour savoir comment resoudre ce problème, j'apprécie également tes commentaires.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    bon, maintenant j'ai modifier mon code ainsi et je n'ai plus d'exeption ... mais j'ai rien qui s'affiche non plus

    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
     Sub DotheTask()
            Dim i As Integer
            For i = 1 To 10
                'Monte que le thread a reçu les bonnes valeurs.
                'Console.WriteLine("Msg # {0} du thread principal avec la valeur", i.ToString)
                deleg = New OneArgSub(AddressOf LblEnvok)
                deleg.Invoke("Msg # " & i & " du thread principal avec la valeur")
                Threading.Thread.Sleep(200)
            Next
        End Sub
     
        Sub LblEnvok(ByVal msg As String)
            SyncLock deleg
                Label1.Invoke(deleg, msg)
            End SyncLock

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    StackOverflowException veut dire que la pile d'appel a atteint sa limite
    quand on appelle une sub, l'appel va sur la pile, si cette sub appelle une autre sub, ca va sur la pile etc... donc tu as une erreur qui fait qu'il y a des appels "sans fin"
    dans ton cas, depuis le thread, tu demande l'appel du délégué, arrivé sur la sub, tu dis au label d'invoker le délégué sur la même sub, qui dis encore au label d'invoker le délégué sur la même sub etc...

    comme dit précédement, il ne faut pas faire deleg.invoke mais label1.invoke(deleg,lestring) depuis le thread, pour dire au thread qui s'occupe du label de mettre sur sa pile (il y a une pile par thread) l'appel de la sub pointée
    et donc dans la sub pointée par le délégue tu laisses juste label1.text = msg

    et le synlock tu peux le retirer il ne sert à rien ici à part tenter de faire bugger le tout

    au passage si tu as 3 threads qui font i de 1 à 10, tu ne verras dans le label que le dernier i d'un thread, ton code est étrange ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut maj Affichage UI par Threads
    bonjour
    voici le schema qu'il y a lieu de retenir pour l'affichage sur l'UI.
    Il implique le test de Control.InvokeRequired,l'appel Asynchrone Form.BeginInvoke du delegue Affichage et l'appel normal de la procedure d'Affichage à partir de Dotask.
    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
     
     
    Imports System.Threading
    Imports System.IO
    Imports System.Text
    Imports System.Net.NetworkInformation
    Public Class Form1
     
     
        Delegate Sub UIOneArgSub(ByVal Msg As String)
        Dim deleg As UIOneArgSub
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'Créer un nouveau thread et définir sont point de départ
            Dim t As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            Dim t1 As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            Dim t2 As New Threading.Thread(New ThreadStart(AddressOf DotheTask))
            'Exécute le nouveau thread
            t.Start()
            t1.Start()
            t2.Start()
        End Sub
     
        Sub DotheTask()
            Dim i As Integer
            For i = 1 To 10
                'Montre que le thread a reçu les bonnes valeurs.
                'Console.WriteLine("Msg # {0} du thread principal avec la valeur", i.ToString)
     
                'Appel normal de la proc d'affichage
                LblEnvok("Msg # " & i & " du thread principal avec la valeur")
                Threading.Thread.Sleep(200)
            Next
        End Sub
     
        Sub LblEnvok(ByVal msg As String)
            'Control.InvokeRequired = False <=>Appel normal du Form
            If Not Label1.InvokeRequired Then
                Label1.Text = msg.ToString
            Else 'non Appel à delegue de Maniere Asynchrone (BeginInvoke) 
                deleg = New UIOneArgSub(AddressOf LblEnvok)
                Me.BeginInvoke(deleg, New Object() {msg})
     
            End If
     
        End Sub
    End Class
    BON CODE....

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

Discussions similaires

  1. [C#] Modifier plusieurs controles "Label"
    Par imer33 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 31/10/2006, 21h53
  2. Modifier les controles d'un formulaire.
    Par vuong1 dans le forum Access
    Réponses: 6
    Dernier message: 19/08/2006, 10h41
  3. [C# Express]Modifier un control dans un formulaire
    Par mickey28 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 19/07/2006, 14h42
  4. Réponses: 3
    Dernier message: 17/07/2006, 16h42
  5. modifier source controle d'une zone de texte dans un état
    Par electrosat03 dans le forum Access
    Réponses: 3
    Dernier message: 20/03/2006, 11h04

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