1. #1
    Futur Membre du Club
    Inscrit en
    septembre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : septembre 2010
    Messages : 14
    Points : 8
    Points
    8

    Par défaut interrompre une communication série

    Bonjour,

    Dans mon application, j'ai une routine qui lis le port série dans une boucle, vu que je connais pas à l'avance combien de fois je dois lire cette boucle est infinie. j'aimerais lors d'un clic par exemple pouvoir terminer la lecture du port sérié et de la boucle.

    merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 326
    Points : 761
    Points
    761

    Par défaut

    Bonjour,

    Tu te déclare un booléen, tu le test dans ta boucle, et tu le modifie dans l'évènement click.

    Bon code,
    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  3. #3
    Futur Membre du Club
    Inscrit en
    septembre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : septembre 2010
    Messages : 14
    Points : 8
    Points
    8

    Par défaut

    Citation Envoyé par J@ckHerror Voir le message
    Bonjour,

    Tu te déclare un booléen, tu le test dans ta boucle, et tu le modifie dans l'évènement click.

    Bon code,
    J@ck.
    lorsque le programme tourne dans la boucle, il me laisse pas la possibilité de cliquer sur un bouton

  4. #4
    Membre actif Avatar de r.morel
    Homme Profil pro
    Dessinateur CAO
    Inscrit en
    août 2014
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Dessinateur CAO
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : août 2014
    Messages : 166
    Points : 256
    Points
    256

    Par défaut

    Salut,
    Il faut mettre la lecture du port sur autre thread pour que l'interface soit accessible durant la lecture
    Pour cela tu peux utiliser un BackGroundWorker. Un tutoriel ici : https://msdn.microsoft.com/fr-fr/lib...(v=vs.95).aspx

    Bon code
    Merci de ainsi que d'utiliser les boutons et

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 326
    Points : 761
    Points
    761

    Par défaut

    Arff oui, je n'y ai pas pensé, en même temps on avait pas des tonnes d'infos .

    Suit le conseil de @r.morel.
    Sinon si tu est en framework 4.5 ou mieux, tu pourrais utiliser l'l'asynchronisme.
    En gros tu appels ta méthode qui contient la boucle dans un Task.Run( ). Tu peut même utiliser un CancellationToken du coup, et l'utiliser dans l'event du bouton.
    A toi de voir.

    J@ck
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  6. #6
    Futur Membre du Club
    Inscrit en
    septembre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : septembre 2010
    Messages : 14
    Points : 8
    Points
    8

    Par défaut

    Citation Envoyé par r.morel Voir le message
    Salut,
    Il faut mettre la lecture du port sur autre thread pour que l'interface soit accessible durant la lecture
    Pour cela tu peux utiliser un BackGroundWorker. Un tutoriel ici : https://msdn.microsoft.com/fr-fr/lib...(v=vs.95).aspx

    Bon code
    d'abord merci à vous pour votre aide, je me permet d'y joindre mon code car je comprend pas le principe du backgroundworder, si quelqu'un pourrais me dire pas à pas ce que je dois faire dans mon code.
    d'avance je vous en remercie

    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
    Option Strict On
    Option Explicit On
    Imports System.IO
    Imports System
     
    Public Class Form1
        Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Short
        Dim nom_fichier As String = "c:\temperature\temperature.txt"
        Private Sub btn_depart_Click(sender As Object, e As EventArgs) Handles btn_depart.Click
            btn_depart.Visible = False
            Lab_sortie.Visible = True
     
            Call ReceptionDonnesSerie()
            End
        End Sub
        Private Sub btn_stop_Click(sender As Object, e As EventArgs)
            btn_depart.Visible = True
            Lab_sortie.Visible = False
     
            End
        End Sub
     
        Sub ReceptionDonnesSerie()
            ' Receive strings from a serial port.
            Dim reponse As MsgBoxResult
            Dim com As IO.Ports.SerialPort = Nothing
            Dim Incoming As String = com.ReadLine()
            Dim lecture As String = ""
     
            Try
                com = My.Computer.Ports.OpenSerialPort("COM6")  
                com.ReadTimeout = 61000
     
                Do
     
                    Lab_temp.Text = Incoming
                    Lab_date.Text = Date.Now.ToString("HH:mm")  
                    Refresh()
                    Call sauvegarde()
     
                Loop
            Catch ex As TimeoutException
                lecture = "Error: Serial Port read timed out."
            Finally
     
                If com IsNot Nothing Then com.Close()
            End Try
            If (GetAsyncKeyState(27) <> 0) Then
                reponse = MsgBox("Arrêt programme ?", MsgBoxStyle.YesNo, "CONTROLE")
                If reponse = vbYes Then
                    BackgroundWorker1.CancelAsync()
                End If
     
            End If
        End Sub
     
        Sub sauvegarde()
            My.Computer.FileSystem.WriteAllText(nom_fichier, Lab_date.Text & ";" & Lab_temp.Text & Convert.ToChar(13) & Convert.ToChar(10), True)  'création fichier si necessaire et écriture
        End Sub
     
     
        Private Sub BackgroundWorker1_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     
        End Sub
     
    End Class

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    juillet 2005
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : juillet 2005
    Messages : 326
    Points : 761
    Points
    761

    Par défaut

    Bonjour,

    Pour que tu comprenne un backgroundWorker il va falloir déjà aller lire de la doc dessus, en commençant par les liens donnés plus haut, auquel on pourra rajouter celui-ci sans oublier

    Puis tenter, en suivant les exemples donnés dans les liens, de modifier ton programme pour le faire fonctionner suivant tes attentes... et si tu rencontres des problèmes demande nous.

    Ton problème est simple, tu a une boucle infini dans ton code et ton appli a une interface graphique.
    Une appli, de base, n'utilise qu'un thread, à la fois pour ton code et pour l'interface (ben oui finalement ton code c'est aussi l'interface...), du coup ta boucle infini tien cet unique thread constamment occupé, donc l'interface ne peut plus réagir. L'idée avec le backgroundWorker c'est de déporter la partie du traitement dans un autre thread, pour ne pas occuper le thread principal infiniment, et rendre à nouveau l'interface réactive. L'utilisation d'un autre thread amene mécaniquement des complications, principalement pour communiquer avec lui, 2 thread ne pouvant pas partager directement leurs ressources (là je suis hors de mes connaissances va falloir aller demander les détails vers d'autres) le BackGroundWorker emmène donc une simplification à ce niveau, en permettant de créer un thread, de lui affecter une tache et de communiquer simplement avec lui. Sans lui il aurait fallut que tu implemente directement des thread en gérant toi même la communication avec ce thread... soit une toute autre pair de manche.

    J@ck.
    Pas de réponse par MP, merci.

    Penser au ça fait plaisir

  8. #8
    Futur Membre du Club
    Inscrit en
    septembre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : septembre 2010
    Messages : 14
    Points : 8
    Points
    8

    Par défaut

    Citation Envoyé par J@ckHerror Voir le message
    Bonjour,

    Pour que tu comprenne un backgroundWorker il va falloir déjà aller lire de la doc dessus, en commençant par les liens donnés plus haut, auquel on pourra rajouter celui-ci sans oublier

    Puis tenter, en suivant les exemples donnés dans les liens, de modifier ton programme pour le faire fonctionner suivant tes attentes... et si tu rencontres des problèmes demande nous.

    Ton problème est simple, tu a une boucle infini dans ton code et ton appli a une interface graphique.
    Une appli, de base, n'utilise qu'un thread, à la fois pour ton code et pour l'interface (ben oui finalement ton code c'est aussi l'interface...), du coup ta boucle infini tien cet unique thread constamment occupé, donc l'interface ne peut plus réagir. L'idée avec le backgroundWorker c'est de déporter la partie du traitement dans un autre thread, pour ne pas occuper le thread principal infiniment, et rendre à nouveau l'interface réactive. L'utilisation d'un autre thread amene mécaniquement des complications, principalement pour communiquer avec lui, 2 thread ne pouvant pas partager directement leurs ressources (là je suis hors de mes connaissances va falloir aller demander les détails vers d'autres) le BackGroundWorker emmène donc une simplification à ce niveau, en permettant de créer un thread, de lui affecter une tache et de communiquer simplement avec lui. Sans lui il aurait fallut que tu implemente directement des thread en gérant toi même la communication avec ce thread... soit une toute autre pair de manche.

    J@ck.
    J'ai trouvé ceci sur le net que j'ai traduit, maintenant reste plus qu'à comprendre comment ça fonctionne (en tout cas ça tourne), donc voici le code si ça peux aider la communauté.

    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    Public Class Form1
     
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Button1.Text = "Démarrer"
            Button2.Text = "Annuler"
            Label1.Text = ""
            Label2.Text = ""
        End Sub
     
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Button1.Enabled = False
            Button2.Enabled = True
            REM Ces propriétés doivent être définies sur True (au moment du design ou de l'exécution) avant d'appeler RunWorkerAsync
            REM Pour s'assurer qu'il supporte les annulations et les rapports Progrès
     
            BackgroundWorker1.WorkerSupportsCancellation = True
            BackgroundWorker1.WorkerReportsProgress = True
    
            REM Appelez cette méthode pour démarrer votre tâche asynchrone.
            BackgroundWorker1.RunWorkerAsync()
        End Sub
     
        Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            REM Pour annuler la tâche, appelez simplement la méthode BackgroundWorker1.CancelAsync.
            Button2.Enabled = False
            BackgroundWorker1.CancelAsync()
        End Sub
     
        Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    
            REM La tâche asynchrone que vous voulez effectuer va ici
            REM Voici un exemple de la façon dont il va généralement.
     
     
            Const Max As Integer = 1000
     
            For i = 1 To Max
    
                REM faire quelque chose
                REM(J'ai mis un sommeil pour simuler le temps consommé)
     
                Threading.Thread.Sleep(100)
                REM Signaler les progrès à intervalles réguliers
     
                BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "en progression...." & i.ToString)
    
                REM Vérifiez à intervalles réguliers pour CancellationPending
                If BackgroundWorker1.CancellationPending Then
                    BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "Annulation...")
                    Exit For
                End If
            Next
    
            REM Tout code de nettoyage est ici
            REM Assurez-vous que vous fermez toutes les ressources ouvertes avant de quitter hors de cette méthode.
            REM Essayez de sauter ce qui n'est pas désespérément nécessaire si CancellationPending est Vrai
            REM Définissez l'e.Cancel sur True pour indiquer à RunWorkerCompleted que vous avez annulé
     
            If BackgroundWorker1.CancellationPending Then
                e.Cancel = True
                BackgroundWorker1.ReportProgress(100, "Annulé.")
            End If
        End Sub
     
        Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            REM Cet événement est déclenché lorsque vous appelez la méthode ReportProgress à partir de votre DoWork.
            REM Tous les indicateurs visuels sur les progrès devraient aller ici.
            Label1.Text = CType(e.UserState, String)
            Label2.Text = e.ProgressPercentage.ToString & "% effectué."
        End Sub
     
        Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            REM Cet événement est déclenché lorsque votre BackgroundWorker se termine.
            REM Il peut avoir sorti Normalement, après avoir terminé sa tâche,
            REM Ou en raison de l'annulation, ou en raison d'une erreur.
     
            If e.Error IsNot Nothing Then
                REM Si BackgroundWorker s'est terminé en raison d'une erreur
                MessageBox.Show(e.Error.Message)
                Label1.Text = "Erreur survenue!"
     
            ElseIf e.Cancelled Then
                REM Sinon, si elle a été annulée
                MessageBox.Show("Tache annulée!")
                Label1.Text = "Tache annulée!"
     
            Else
                REM Sinon il a terminé normalement
                MessageBox.Show("Tache effectuée!")
                Label1.Text = "Tache effectuée!"
            End If
     
            Button1.Enabled = True
            Button2.Enabled = False
        End Sub
     
    End Class

Discussions similaires

  1. cas d'utilisation pour une communication port série
    Par tintine dans le forum Cas d'utilisation
    Réponses: 1
    Dernier message: 23/05/2015, 18h58
  2. Réponses: 0
    Dernier message: 11/09/2014, 13h27
  3. Fermer une communication port série à la fermeture d'un GUI
    Par christophe_halgand dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 21/07/2012, 07h47
  4. Insérer une pause dans une communication série
    Par aiantreize dans le forum MATLAB
    Réponses: 5
    Dernier message: 23/04/2007, 12h25
  5. [API] Communication série NON-bloquante : OVERLAPPED/Thread
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/11/2003, 13h43

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