简体   繁体   中英

C# Serial DataReceived Event Invoke Function Not Working Properly

I make a winform program to read data from serial port and display it in textbox. The data will be sent from external device at every 5 sec interval. The first data is "1 followed by "2" and then "3" and repeat the same pattern forever.
I will make pictureBox1, pictureBox2, pictureBox3 visisble and play gif when data "1", "2" and "3" received respectively. The problem is sometime the pictureBox does not switch to the next respective one even though the next data has arrived. I am not sure whether I am using the invoke function correctly?

public Form1()
{
    InitializeComponent();
    SerialPortProgram();
    pictureBox1.Image=
    Image.FromFile(@"C:\Users\user\Downloads\Gif#1.gif");
    pictureBox2.Image = 
    Image.FromFile(@"C:\Users\user\Downloads\Gif#2.gif");
    pictureBox3.Image = 
    Image.FromFile(@"C:\Users\user\Downloads\Gif#3.gif");
}

// Create the serial port with basic settings
private SerialPort port = new SerialPort("COM17", 9600, Parity.None, 8, StopBits.One);

private void SerialPortProgram()
{
    // Attach a method to be called when there
    // is data waiting in the port's buffer
    port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

    // Begin communications
    port.Open();

    // Enter an application loop to keep this thread alive
    // Application.Run();        // if this Application.Run() is not commented out, Form1 will not be displayed
}

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // Show all the incoming data in the port's buffer
    string data = (port.ReadExisting());
    Log(data);
    if (data == "1")
    {
        gif1Showl();
    }

    if (data == "2")
    {
        gif2Show();
    }

    if (data == "3")
    {
        gif3Show();
    }
}


private void Log(string msg)
{
    textBox1.Invoke(new EventHandler(delegate
    {
        textBox1.AppendText(msg);
    }));
}

private void gif1Showl()
{
    this.Invoke(new ThreadStart(() =>
    {
        pictureBox1.Visible = true;
        pictureBox1.Enabled = true;
        pictureBox2.Visible = false;
        pictureBox2.Enabled = false;
        pictureBox3.Visible = false;
        pictureBox3.Enabled = false;
    }));
}

private void gif2Show()
{
    this.Invoke(new ThreadStart(() =>
    {
        pictureBox1.Visible = false;
        pictureBox1.Enabled = false;
        pictureBox2.Visible = true;
        pictureBox2.Enabled = true;
        pictureBox3.Visible = false;
        pictureBox3.Enabled = false;
    }));
}

private void gif3Show()
{
    this.Invoke(new ThreadStart(() =>
    {
        pictureBox1.Visible = false;
        pictureBox1.Enabled = false;
        pictureBox2.Visible = false;
        pictureBox2.Enabled = false;
        pictureBox3.Visible = true;
        pictureBox3.Enabled = true;
    }));
}

You should check if invoking is needed and call your delegate. Creating a new thread to update the UI itself is wrong.

MethodInvoker methodInvokerDelegate = delegate() 
{ 
    pictureBox1.Visible = false;
    pictureBox1.Enabled = false;
    pictureBox2.Visible = false;
    pictureBox2.Enabled = false;
    pictureBox3.Visible = true;
    pictureBox3.Enabled = true; 
};

//This will be true if Current thread is not UI thread.
if (this.InvokeRequired)
    this.Invoke(methodInvokerDelegate);
else
    methodInvokerDelegate();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM