none
begininvoke bloque l'UI, attente transmission série RRS feed

  • Question

  • Bonjour, je programme actuellement une application pour faire de l'acquisition de données avec un arduino. La transmission série fontionne bien mais le thread asynchrone appelé par le Control.BeginInvoke fonctionne en bloquant le thread de l'UI. J'aimerais pouvoir utiliser l'UI en même temps que l'échange des données entre le PC et l'Arduino.

    voici mon code :

    'Espace de noms permettant la gestion des ports série
    Imports System.IO.Ports.SerialPort
    
    Imports System
    Imports System.Threading
    Imports System.Runtime.InteropServices
    Imports Microsoft.Office.Interop
    
    Public Class Form1
    
        'Liste des ports COM disponibles
        Dim a() = GetPortNames()
        Dim cmdByte As Byte
        Dim releve() As String
    
        'Variables pour Excel
    
        'Dim xls As Excel.Application
        'Dim xlsfeuille As Excel.Worksheet
        'Dim xlsclasseur As Excel.Workbook
    
        'Invocation de la méthode de réception série
        Delegate Sub InvocationDeleguee()
    
        'Initialisation de la fenêtre lors de son chargement
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    
            'Ajout des ports com disponible dans la ComboBox
            For Each gatto In a
                ComboBox1.Items.Add(gatto)
            Next
    
            ReDim releve(0)
    
            'xls = CreateObject("Excel.Application")
            'xlsclasseur = xls.Workbooks.Add
            'xlsfeuille = xlsclasseur.Worksheets(1)
    
            'Initialisation de la barre de statut et du label d'affichage des valeurs
            ToolStripStatusLabel1.Text = ""
            Label1.Text = ""
    
            Button2.Enabled = True
            Button1.Enabled = False
    
        End Sub
    
        'Validation du choix du port COM et envoi d'instruction à l'Arduino
        Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    
            'Ouverture et paramétrage du port si l'un des ports disponibles à été choisi
            If Not (ComboBox1.Text = "") And Not Button1.Enabled Then
    
                'Désactivation du bouton de validation du port COM
                ToolStripStatusLabel1.Text = "Port sélectionné : " & ComboBox1.Text
                'Button2.Enabled = False
                Button1.Enabled = True
                cmdByte = 1
    
                SerialPort1.PortName = ComboBox1.Text
                SerialPort1.BaudRate = 19200
                SerialPort1.Parity = IO.Ports.Parity.None
                SerialPort1.StopBits = 1
                SerialPort1.Open()
                SerialPort1.Write(cmdByte)
    
            End If
    
        End Sub
    
        'Evènement réception de données
        Private Sub SerialPort1_OnComm() Handles SerialPort1.DataReceived
    
            'Invocation de la méthode de traitement des données
            Label1.BeginInvoke(New InvocationDeleguee(AddressOf MethodeDeleguee))
    
        End Sub
    
        'Traitement des données
        Private Sub MethodeDeleguee()
    
            releve(releve.Length - 1) = SerialPort1.ReadLine()
            ReDim Preserve releve(releve.Length)
    
        End Sub
    
        'Envoi du signal d'arrêt des requêtes de l'arduino au comparateur
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            cmdByte = 0
            SerialPort1.Write(cmdByte)
        End Sub
    
    End Class
    

    lundi 6 août 2012 07:54

Réponses

  • Bonjour,

    Le but de BeginInvoke est précisemment d'appeler qq chose sur le thread de l'UI ce qui ne semble pas nécessaire ici. Le principe serait plutôt de faire le maximum dans DataReceived qui comme l'indique la doc est "déclenché sur un thread secondaire") et d'appeler BeginInvoke uniquement pour manipuler l'UI.

    Accessoirement il est sans doute préférable d'éviter autant que possible Redim Preserve et par exemple d'utiliser un tableau assez long et de ne le redimensionner que si il doit efffectivement être plus grand (ce qui ne se produira que peu souvent ou au pire peu puis plus du tout lorsqu'il sera assez grand).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marqué comme réponse Ervann lundi 6 août 2012 09:44
    lundi 6 août 2012 09:09
    Modérateur

Toutes les réponses

  • et ... désolé pour cette mise en couleur automatique déplorable, mais ce n'est pas de mon fait ...
    lundi 6 août 2012 07:55
  • Bonjour,

    Le but de BeginInvoke est précisemment d'appeler qq chose sur le thread de l'UI ce qui ne semble pas nécessaire ici. Le principe serait plutôt de faire le maximum dans DataReceived qui comme l'indique la doc est "déclenché sur un thread secondaire") et d'appeler BeginInvoke uniquement pour manipuler l'UI.

    Accessoirement il est sans doute préférable d'éviter autant que possible Redim Preserve et par exemple d'utiliser un tableau assez long et de ne le redimensionner que si il doit efffectivement être plus grand (ce qui ne se produira que peu souvent ou au pire peu puis plus du tout lorsqu'il sera assez grand).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marqué comme réponse Ervann lundi 6 août 2012 09:44
    lundi 6 août 2012 09:09
    Modérateur
  • Merci à vous,

    en rebasculant le code dans le DataReceived, je me suis rendu compte que le beginInvoke n'était pas nécessaire...

    Donc problème résolu

    lundi 6 août 2012 09:46