2011-12-20 2 views
0

Je voudrais des conseils sur le filetage que je suis nouveau à ce sujet. J'ai lu plusieurs articles sur le filetage en ligne. Je lis les données des ports COM. Je voudrais utiliser le threading tel qu'il lira les données toutes les 5 secondes et mettra à jour les données sur la liste. Actuellement, toutes les données sont en cours de lecture. Je ne sais pas par où commencer. Où dois-je commencer à mettre mes codes de fil? J'utilise Windows Form, C# VS2008.Lire les ports COM en utilisant le filetage dans C#

Voici mon code pour lire les données des ports com:

void datareceived(object sender, SerialDataReceivedEventArgs e) 
    {    
     myDelegate d = new myDelegate(update); 
     listBox1.Invoke(d, new object[] { }); 

    } 


    public void update() 
    {   

     while (serialPortN.BytesToRead > 0) 
      bBuffer.Add((byte)serialPortN.ReadByte()); 
     ProcessBuffer(bBuffer); 

    } 

    private void ProcessBuffer(List<byte> bBuffer) 
    {    

     int numberOfBytesToRead = 125; 

     if (bBuffer.Count >= numberOfBytesToRead) 
     {    


       listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + " " + " HR: " + (bBuffer[103].ToString())); 


      // Remove the bytes read from the list 
      bBuffer.RemoveRange(0, numberOfBytesToRead); 

     } 

    }   

Merci à tous!

Répondre

2

Pourquoi ne pas utiliser une minuterie? Mettre dans la méthode InitializeComponent de la forme qui convient,

using System.Timers; 

private void InitializeComponent() 
{ 
    this.components = new System.ComponentModel.Container(); 
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
    this.Text = "Form1"; 

    Timer timer = new Timer(); 

    timer.Interval = 5000; 
    timer.Elapsed += new ElapsedEventHandler(TimerElapsed); 

    //timer.Enabled = true; // you may need this, but probably not if you are calling the start method. 
    timer.Start(); 
} 

void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    // put your code here to read the COM port 
} 

Le seul autre problème avec ce code est que vous obtiendrez une exception opération de la Croix-fil non valide.

Vous devrez modifier votre code comme celui-ci,

private void ProcessBuffer(List<byte> bBuffer) 
{ 
    int numberOfBytesToRead = 125; 

    if (bBuffer.Count >= numberOfBytesToRead) 
    { 
     this.Invoke(new Action(() => 
     { 
      listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + " " + " HR: " + (bBuffer[103].ToString())); 
     }); 

     // Remove the bytes read from the list 
     bBuffer.RemoveRange(0, numberOfBytesToRead); 
    } 
} 

La raison est que la méthode ProcessBuffer sera en cours d'exécution sur un thread d'arrière-plan. Les threads d'arrière-plan ne peuvent pas accéder aux composants de l'interface utilisateur sur le thread d'interface utilisateur. Donc, vous devez appeler this.Invoke qui va exécuter cette mise à jour à la liste sur le thread de l'interface utilisateur.

Jetez un oeil ici si vous voulez en savoir plus sur la méthode Invoke,

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

MISE À JOUR:

donc dans la méthode TimerElapsed vous voulez appeler votre code, mais il est pas clair pour moi quelle partie de votre code il devrait appeler? À quoi sert la méthode 'datareceived', il n'y a rien qui l'appelle dans votre extrait de code.

donc je devine que ce sera cela,

void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    Update(); 
} 

public void Update() 
{ 
    while (serialPortN.BytesToRead > 0) 
     buffer.Add((byte)serialPortN.ReadByte()); 
    ProcessBuffer(buffer); 
} 

Il est-il logique de ne pas être d'appeler la méthode ProcessBuffer, car d'où viendra le tampon de?

Si je ne suis pas sur la bonne voie, développez peut-être votre exemple de code, et je serai heureux de vous aider. Veuillez noter quelques changements de style que j'ai apportés à votre code (n'hésitez pas à les prendre ou à les quitter), une méthode en C# devrait commencer par une lettre majuscule, et appeler la variable bBuffer n'est pas standard en C#. Un autre point si cette méthode est seulement appelée depuis la classe, elle devrait être privée.

+0

Salut Peter, Merci pour votre réponse. Pour les données de port COM de lecture, j'ai inséré les données sous un événement de clic de bouton. Dois-je mettre le gestionnaire d'événements de clic de bouton sous le minuteur de vide? Merci ! – fb69

+0

Je ne suis pas 100% suivant. Que voulez-vous dire que vous avez inséré les données dans un événement de clic sur un bouton? Inséré quelles données? Si vous voulez savoir si vous pouvez mettre le gestionnaire d'événement de clic de bouton après le TimerElapsed de vide dans le fichier de code, alors oui vous pouvez. – peter

+0

Désolé Peter, Ce que je voulais dire, c'est que dans la méthode du temps écoulé, est-ce que je peux insérer le codage du tampon de processus?Depuis la méthode du tampon de processus qui traite les données. – fb69