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 :

System.InvalidOperationException*: 'Impossible d'appeler Invoke ou BeginInvoke sur un contrôle tant que le han [Débutant]


Sujet :

VB.NET

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2022
    Messages : 2
    Points : 3
    Points
    3
    Par défaut System.InvalidOperationException*: 'Impossible d'appeler Invoke ou BeginInvoke sur un contrôle tant que le han
    Bonjour à tous,
    Je me permets de vous solliciter suite à un problème que je rencontre.

    Je développe actuellement une application de surveillance.

    Celle ci se compose d'une Form Windows dans laquelle, nous avons :
    - un bouton (btn_Test_CLick)
    - une TextBox (txBx_Lecture_CSV)

    Ce que je cherche à faire :
    - en cliquant sur le bouton, je crée un file System Watcher qui devra détecter si un fichier est modifié sur le répertoire surveillé
    - lorsque le fichier est effectivement modifié, un message du genre "le fichier est modifié"

    Pour cela, je dispose de 2 classes : Form1.vb et bouton.vb dont voici les codes :
    Form1 .vb
    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
    Imports System.IO
    Imports System.Threading
     
    Public Class Form1
        '--Ecoute du répertoire
     
     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            '--AU chargement de la forme Windows, on déclare un nouvel objet de type bouton
            mBouton = New bouton
        End Sub
     
        '-----------------------------------------------------------------------------------------------------------------------------
        '--Déclaration du WithEvent dans la classe
        Private WithEvents mBouton As bouton
     
     
        Private Sub btn_Test_CLick_Click(sender As Object, e As EventArgs) Handles btn_Test_CLick.Click
            Application.DoEvents()
            mBouton.simule_clic(sender, e)
        End Sub
     
    End Class

    bouton.vb
    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
    Imports System.IO
     
    Public Class bouton
     
        '--définir un evenement
        Public Event Click_Bouton_Test(ByVal sender As Object, ByVal e As EventArgs)
     
        '--Méthode appelée
        Public Sub simule_clic(ByVal sender As Object, ByVal e As EventArgs)
            Dim watcher = New FileSystemWatcher("C:\test_robot")
     
            '--Déclaration des notifications
            '-- Sur les attributs, la date de création, le nom du répertoire
            '-- le nom du fichier, le dernier accès, la dernière écriture
            '-- sur la taille ou la sécurité du fichier
            watcher.NotifyFilter = NotifyFilters.Attributes Or
                                       NotifyFilters.CreationTime Or
                                       NotifyFilters.DirectoryName Or
                                       NotifyFilters.FileName Or
                                       NotifyFilters.LastAccess Or
                                       NotifyFilters.LastWrite Or
                                       NotifyFilters.Security Or
                                       NotifyFilters.Size
            '--Syntaxe de l'instruction AddHandler 
            AddHandler watcher.Changed, AddressOf OnChanged
            AddHandler watcher.Created, AddressOf OnCreated
            AddHandler watcher.Deleted, AddressOf OnDeleted
            AddHandler watcher.Renamed, AddressOf OnRenamed
            AddHandler watcher.Error, AddressOf OnError
     
            '--Filtre uniquement sur les fichiers textes
            watcher.Filter = "*.txt"
            '--inclusion des sous-répertoires
            watcher.IncludeSubdirectories = True
            '--obtient une valeur indiquant si le composant est activé
            watcher.EnableRaisingEvents = True
        End Sub
     
        Public Sub OnChanged(sender As Object, e As FileSystemEventArgs)
            If e.ChangeType <> WatcherChangeTypes.Changed Then
                Return
            End If
            Dim dt As DateTime = Now()
            Static tp As Long = 0
            If e.ChangeType = WatcherChangeTypes.Changed Then
                '--Systeme de timer pour empecher que l'evenement Onchanged ne se déclenche 2 fois consécutivement
                If ((dt.Ticks - tp) < 400000 AndAlso e.ChangeType = WatcherChangeTypes.Changed) Then
                    Return
                End If
                tp = dt.Ticks
     
                Form1.Invoke(New MethodInvoker(Sub()
                                                   Form1.txtBx_Operations_Fichiers.AppendText("Changement du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
                                               End Sub))
     
     
            End If
        End Sub
     
        Public Sub OnCreated(sender As Object, e As FileSystemEventArgs)
            Dim value As String = $"Created: {e.FullPath}"
     
            Form1.Invoke(New MethodInvoker(Sub()
                                               Form1.txtBx_Operations_Fichiers.AppendText("Création du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
                                           End Sub))
        End Sub
    End Class
    Le problème se situe au niveau de cette instruction dans la classe bouton.vb où je cherche à mettre à jour la textBox dans la Form:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Form1.Invoke(New MethodInvoker(Sub()
                                               Form1.txtBx_Operations_Fichiers.AppendText("Création du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
                                           End Sub))
        End Sub
    J'ai le message comme quoi il est impossible d'appeler la méthode Invoke.
    J'ai compris qu'il s'agissait d'un problème de Thread ou j'essayais de mettre à jour la textBox avec un Thread différent de celui qui avait crée la Windows Form et du coup, cela n'était pas sécurisé.

    Ma question est la suivante : comment puis-je écrire dans ma Textbox quand même ?
    Je suis passé par la création d'un nouveau Thread, j'ai voulu utilisé la methode Shown (plutot que Form1_Load), et les delegates mais rien n'y fait, je m'y prend mal.

    Pouvez-vous m'apporter votre aide ?

    Par avance, merci

  2. #2
    Candidat au Club
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2022
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Méa Culpa, après une recherche, le code suivant dans mon invoke fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Dim main As Form1 = CType(Application.OpenForms(0), Form1)
                main.Invoke(New MethodInvoker(Sub()
                                                  Form1.txtBx_Operations_Fichiers.AppendText("Changement du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
                                              End Sub))
    Cela signifierait-il que ma déclaration de 'main' crée une instance de Form1 qui est directement exploitable ?
    J'avoue que j'ai un peu de mal à comprendre et toute aide serait la bienvenue.

    Par avance, merci

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Form1 est une classe. Tu ne peux pas appeler une méthode de cette classe sans créer une instance de cette classe.
    Seules exceptions à cette règle, les méthodes statiques (mais ces méthodes statiques ne peuvent pas faire référence à Me, elles sont autonomes).

    Et ta déclaration de main ne créé aucune instance.
    Elle ne fait que récupérer via Application.OpenForms(0) l'instance déjà existante.

    Il te manques les notions élémentaires de la POO qui te permettraient de te rendre compte que ce que tu fais n'est pas une bonne idée.
    Tu es en train de créer une classe fortement liée à Form1 et donc inutilisable ailleurs.
    Et ceci sans parler du fait que tu as mis du comportement directement dans la classe du bouton au lieu de laisser l'appelant décider.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 28/01/2020, 20h24
  2. Réponses: 2
    Dernier message: 05/09/2019, 13h10
  3. Réponses: 0
    Dernier message: 20/08/2019, 10h04
  4. Réponses: 5
    Dernier message: 09/04/2014, 22h53
  5. Réponses: 4
    Dernier message: 01/03/2012, 16h20

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