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 :

Attendre sans bloquer l'application [Débutant]


Sujet :

VB.NET

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Attendre sans bloquer l'application
    Bonjour,

    Je vous expose mon petit problème.

    Mon application communique avec une autre application. Par un simple clic sur un bouton j'envoie un ordre à l'application qui doit me retourner une information dès que cette ordre est réalisé.
    Ceci se fait avec le simple code ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     Private Sub Button17_Click(sender As Object, e As EventArgs) Handles Button17.Click
            Try
                Dim ordre As String
                Dim recu As String
                TextBox19.Text = ""
                ordre = TextBox18.Text
                recu = objArduino.CommandString(ordre, False)
                TextBox19.Text = recu
            Catch ex As Exception
                MessageBox.Show("Problème connexion avec l'Arduino.", "Arduino", MessageBoxButtons.OK, MessageBoxIcon.None)
            End Try
        End Sub
    Cela fonctionne sauf que :
    - en attendant la réponse (pour les plus courtes 1 à 2 secondes) mon appli est bloquée et cela je ne le voudrais pas ;
    - pour certaines réponses supérieures à 5 secondes, j'ai ma messageBox qui s'affiche car le délai de réponse est trop long (si je retire le Try, j'ai le message d'erreur Timed out waiting for received data).

    Ce que je voudrais c'est que l'attente de la réception de l'information se fasse tranquillement pénard dans son coin et que je puisse utiliser librement mon appli. Lorsque l'info arrive, elle s'affiche dans la textbox.
    J'ai lu que cela semble possible mais je n'y comprend rien. Entre les thread, les invoke, les delegate et backgrondworker je ne sais pas par où commencer.

    Donc voila, je viens chercher de l'aide.

    Merci

  2. #2
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 235
    Points : 359
    Points
    359
    Par défaut
    Bonjour,
    Mon application communique avec une autre application.
    Avec une autre application ou avec une interface externe via le port rs-232 ?
    Par nature les mots, ils sont flous, c'est une fois alignés qu'ils se précisent.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    J'ai écrit application par manque de connaissances informatiques mais je dirais que c'est une interface qui est reliée à un matériel (l'arduino) par le port série. Cette interface contient le protocole de communication avec le matériel.

    Plusieurs applications peuvent se connecter en même temps à l'interface et plusieurs matériels peuvent être connectés à l'interface.

  4. #4
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 235
    Points : 359
    Points
    359
    Par défaut
    Ahh...
    je me disais bien que j'avais déjà vu arduino quelque-part...
    Explique un peu ce qu'as-tu déjà fait?
    Dans ta Form dois déjà insérer un "SerialPort" (c'est le composant qui va permettre la communication série (rs-232), entre ton application et le arduino) c'est fait?
    Par nature les mots, ils sont flous, c'est une fois alignés qu'ils se précisent.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 235
    Points : 359
    Points
    359
    Par défaut
    Re:
    Bon, je dois sortir alors j'avance un peu...

    Entre les thread, les invoke, les delegate et backgrondworker je ne sais pas par où commencer.
    Ci-dessous je te mets un exemple avec un SerialPort, boutons et textbox crées dynamiquement, c'est-à-dire qu'ils sont crées à partir du code, tu as juste à créer un nouvel projet vierge et coller ce code:
    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
     
    Option Explicit On
    Option Strict On
     
    Imports System
    Imports System.ComponentModel
    Imports System.Threading
    Imports System.IO.Ports
     
    Public Class Form1
        Dim WithEvents SerialPort1 As SerialPort = New System.IO.Ports.SerialPort
        Dim TexteRecu As New TextBox
        Dim TexteAEnvoyer As New TextBox
        Dim BtnEnvoi As New Button
        Delegate Sub SetTextCallback(ByVal Recu As String)
     
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            System.Threading.Thread.Sleep(100) 'Petite pause de 100 ms
            SetText(SerialPort1.ReadExisting())
        End Sub
     
        Private Sub SetText(ByVal Recu As String)
            If Me.TexteRecu.InvokeRequired Then
                Dim d As New SetTextCallback(AddressOf SetText)
                Me.Invoke(d, New Object() {Recu})
            Else
                'Ici c'est le moment où il recoit des données 
                'sans avoir à attendre avec un quelconque timer ou autre (c'est un thread complètement à part de ton application)
                Me.TexteRecu.Text = Recu
            End If
        End Sub
     
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            SerialPort1.Close() 'fermeture du port à la fermeture du port
        End Sub
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            With SerialPort1
                .PortName = "COM4" 'à modifier selon ton n° de port
                .BaudRate = 9600
                .Parity = Parity.None
                .DataBits = 8
                .StopBits = StopBits.One
            End With
            SerialPort1.Open() 'ouverture du port au démarrage de l'appli
     
            'création des controles sur la Form:
            Me.Controls.Add(TexteRecu)
            TexteRecu.Location = New Point(CInt(Me.Width / 3), CInt(Me.Height / 3))
            TexteRecu.Enabled = False
            Me.Controls.Add(TexteAEnvoyer)
            TexteAEnvoyer.Location = New Point(TexteRecu.Location.X, TexteRecu.Location.Y + TexteAEnvoyer.Height + 5)
            Me.Controls.Add(BtnEnvoi)
            BtnEnvoi.Location = New Point(TexteAEnvoyer.Location.X + TexteAEnvoyer.Width + 5, TexteAEnvoyer.Location.Y)
            BtnEnvoi.Text = "Envoyer"
            AddHandler BtnEnvoi.Click, AddressOf BtnEnvoi_Click
        End Sub
     
        Private Sub BtnEnvoi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            'Envoi des données contenues dans TexteAEnvoyer
            If TexteAEnvoyer.Text.Length > 0 Then SerialPort1.Write(TexteAEnvoyer.Text)
        End Sub
    End Class
    Par nature les mots, ils sont flous, c'est une fois alignés qu'ils se précisent.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par ACIVE_CS Voir le message
    Bon, je dois sortir alors j'avance un peu...
    Y a pas d'urgence.

    Pour ton exemple, ce qui m'embète c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            System.Threading.Thread.Sleep(100) 'Petite pause de 100 ms
            SetText(SerialPort1.ReadExisting())
        End Sub
    car je n'ai pas de port série de déclaré dans ma form. C'est l'interface qui s'occupe du port série. Je vais d'ailleurs lui greffer ton exemple car elle aussi risque de planter si le temps de réponse de l'arduino dépasse le timeout.

    Mon appli se connecte à l'interface ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public objArduino As ASCOM.DriverAccess.Telescope
     
    objArduino = New ASCOM.DriverAccess.Telescope(My.Settings.Telescope)
    objArduino.Connected = True

    La demande d'information s'effectue avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    recu = objArduino.CommandString(ordre, False)
    objArduino est donc l'interface, CommandSrting est une fonction de l'interface qui retourne un résultat et ordre est ce que doit faire la fonction. (False sert au protocole de communication sans importance ici).

    Donc ce n'est pas le port com qui est à surveillé périodiquement pour savoir s'il a quelque chose à me dire mais l'interface objArduino. J'ai bien sur essayé de bidouiller avant d'écrire ce message mais sans résultat.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    J'ai réglé une partie du problème. L'appli ne se fige plus lorsqu'elle attend la réponse. J'ai compris le fonctionnement du thread.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim thread As System.Threading.Thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub Button17_Click(sender As Object, e As EventArgs) Handles Button17.Click
            TextBox19.Text = ""
            ordre = TextBox18.Text
            thread = New System.Threading.Thread(AddressOf arduino)
            thread.Start()
        End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub arduino()
            Try
                recu = objArduino.CommandString(ordre, False)
                TextBox19.Text = recu
            Catch ex As Exception
                MessageBox.Show("Problème connexion avec l'Arduino.", "Arduino", MessageBoxButtons.OK, MessageBoxIcon.None)
            End Try
        End Sub
    Pour l'histoire des controles créés dans un thread et modifié par un autre thread, j'ai ajouté dans le form load
    Me.CheckForIllegalCrossThreadCalls = False

    Je pense que ce n'est pas très propre et que je le supprimerai dès que j'aurai compris les invoke

    J'ai toujours le problème pour les réponses dont la durée est supérieur à 5 secondes (erreur de timeout) mais là il faut que je regarde l'interface.

    merci

    bonne nuit

  8. #8
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 235
    Points : 359
    Points
    359
    Par défaut
    Re:
    Apparemment tu utilises un composant dédié spécifique à ton hardware, (ce qui remplace le SerialPort) je crains qu'on ne pourra pas trop t'aider dans ce cas

    car je n'ai pas de port série de déclaré dans ma form.
    Dans mon code j'ai crée le serialport dynamiquement (dans mon code) comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim WithEvents SerialPort1 As SerialPort = New System.IO.Ports.SerialPort
    Or dans ton code tu fais la même chose mais avec ton composant ASCOM (dont nous ne connaissons pas le fonctionnement) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public objArduino As ASCOM.DriverAccess.Telescope
    objArduino = New ASCOM.DriverAccess.Telescope(My.Settings.Telescope)
    J'ai un peu "fouillé" et "googolisé" et jai trouvé CECI:

    Tu peux télécharger le projet entier en cliquant sur "download snapshot"
    Il me semble qu'il fait ce que tu cherches.
    Par contre je crois que c'est du VB.Net 2013, or sur ma machine je n'ai que le 2010 d'installé et je ne peux pas le lancer, mais on peux voir le code.
    Par nature les mots, ils sont flous, c'est une fois alignés qu'ils se précisent.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Mes deux problèmes initiaux n'existent plus.

    "- en attendant la réponse (pour les plus courtes 1 à 2 secondes) mon appli est bloquée et cela je ne le voudrais pas ;"
    comme dit plus haut, j'ai compris (j'espère) le fonctionnement des thread, j'ai donc mis la transmission de l'ordre et la demande de réponse dans un thread secondaire.


    "- pour certaines réponses supérieures à 5 secondes, j'ai ma messageBox qui s'affiche car le délai de réponse est trop long (si je retire le Try, j'ai le message d'erreur Timed out waiting for received data)."
    Pour ce problème, j'ai modifier le timeout de l'interface pour le passer de 5s par défaut à 20s.

    donc résolu

    Merci pour l'aide

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/10/2011, 13h45
  2. EDT attendre sans bloquer GUI
    Par kaoualeo dans le forum EDT/SwingWorker
    Réponses: 19
    Dernier message: 05/11/2010, 10h48
  3. [C# 2] Faire une pause sans bloquer l'application
    Par Tamahome dans le forum ASP.NET
    Réponses: 7
    Dernier message: 09/04/2008, 12h53
  4. Réponses: 4
    Dernier message: 24/10/2006, 02h24
  5. Afficher un message sans bloquer les autres traitements??
    Par Ben_Le_Cool dans le forum Langage
    Réponses: 7
    Dernier message: 13/10/2005, 00h21

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