[gelöst] Textboxänderung wirft (Thread-)Fehler aus



  • Hallo,

    ich habe ein kleines Versuchsprogramm geschrieben um die COM-Verbindung zu einem Mikrocontroller zu testen. Der Mikrocontroller ist darauf programmiert, das empfangene Byte zurückzusenden.

    Um das zurückgesendete Byte abzurufen verwende ich das SerialPort-Ereignis DataReceived. Wird dieses nun in die Textbox tbEmpfangen geschrieben erhalte ich den Fehler "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement tbEmpfangen erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.". Kann mir da jemand weiterhelfen?

    using System;
    using System.IO.Ports;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                SerialPort.PortName = "COM4";
                SerialPort.BaudRate = 9600;
                SerialPort.Parity = Parity.None;
                SerialPort.StopBits = StopBits.One;
                SerialPort.Handshake = Handshake.None;
                try
                {
                    SerialPort.Open();
                }
                catch (Exception)
                {
                    MessageBox.Show("Fehler! COM4 konnte nicht geöffnet werden");
                }
            }
    
            private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                while (SerialPort.BytesToRead > 0)
                {
                    char cPuffer = (char) SerialPort.ReadChar();
                    tbEmpfangen.Text += cPuffer.ToString() + "\r\n"; //Hier kommt der Fehler
                    //MessageBox.Show(cPuffer.ToString());  Das funktioniert        
                }
            }
    
            private void tbSenden_TextChanged(object sender, EventArgs e)
            {
                string sSenden = tbSenden.Text;
                tbGesendet.Text += sSenden + "\r\n";
                tbSenden.Text = "";
                SerialPort.Write(sSenden);
                while (SerialPort.BytesToWrite > 0);
    
            }
        }
    }
    


  • Naja, der Name ist Programm. Du kannst Zugriffe auf ein Component nur aus dem Thread machen der es erstellt hat, normalerweise der GUI-Thread. Synchronisation geht so:

    void SetText(string text)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new Action<string>(SetText), text);
        }
        else
        {
            tbEmpfangen.Text = text;
        }
    }
    

    EDIT:
    Schau mal, fast das selbe Problem auf board.gulli.com.



  • Das heißt Ereignisse bekommen alle bei der Ausführung ihren eigenen Thread?



  • neo47 schrieb:

    Das heißt Ereignisse bekommen alle bei der Ausführung ihren eigenen Thread?

    Nein.
    SerialPort.DataReceived kommt aus einem zweiten Thread. Steht auch in der Dokumentation des Events.



  • ok, jetzt hab ichs auch gelesen. 😉

    Vielen Dank!


Log in to reply