试图在UI-Thread中设置变量

时间:2014-09-30 13:44:21

标签: c# multithreading serial-port

我使用此代码从加权比例读取,我成功读取了它的重量值但是当试图为下一个重量值设置变量hex = ""时,我无法在文本框中获取它,它出现非常快,然后再次消失,如果我使用hex =“”启用跟踪程序,结果是按预期的,但如果运行程序没有跟踪它,那么闪烁的值和文本框变为空:(任何想法< / p>

        string hex = "";
        private delegate void Closure();
        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (InvokeRequired)     
            {                
                BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     
            }
            else
            {
                if (_serialPort.BytesToRead > 0)
                {
                    //hex = "";  <- Without this different weight values appears one after another. If applied then happens what explained above.
                    while (_serialPort.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
                    {                        
                        hex += string.Format("{0:X2} ", _serialPort.ReadByte());                        
                    }

                    byte[] data = FromHex(hex.Trim());
                    textBox1.Text = Encoding.ASCII.GetString(data).Trim();
                }
            }
        }

        public byte[] FromHex(string aHex)
        {
            aHex = aHex.Replace(" ", "");
            byte[] raw = new byte[aHex.Length / 2];
            for (int i = 0; i < raw.Length; i++)
            {
                raw[i] = Convert.ToByte(aHex.Substring(i * 2, 2), 16);
            }
            return raw;
        }

这是开始收听的代码:

        private void button1_Click(object sender, EventArgs e)
        {
            //<-- This block ensures that no exceptions happen
            if (_serialPort != null && _serialPort.IsOpen)
                _serialPort.Close();
            if (_serialPort != null)
                _serialPort.Dispose();
            //<-- End of Block


            /*--- OHAUS Ranger Count Config ---*/
            //http://us.ohaus.com/us/en/home/support/faq.aspx
            _serialPort = new SerialPort(comboBox1.Text);
            _serialPort.BaudRate = 2400;
            _serialPort.Parity = Parity.None;
            _serialPort.DataBits = 7;
            _serialPort.StopBits = StopBits.Two;
            _serialPort.Handshake = Handshake.None;
            /*--- End OHAUS Ranger Count Config ---*/

            label1.Text = "Listening on " + _serialPort.PortName + "...";

            _serialPort.DataReceived += SerialPortOnDataReceived;       //<- Here I add the event
            _serialPort.Open();     //<-- make the comport listen

        }

enter image description here

3 个答案:

答案 0 :(得分:1)

在按下打印键时调用的方法内,可以添加串口事件处理程序:

_serialPort.OnDataReceived+=SerialPortOnDataReceived;

然后,在SerialPortOnDataReceived方法结束时(成功读取之后),从串行端口对象中删除事件处理程序。这将使其停止在串口上侦听新数据,直到您再次按下打印。

private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
    if (InvokeRequired)     
    {                
        BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     
    }
    else
    {
        if (_serialPort.BytesToRead > 0)
        {
            //hex = "";  <- Without this different weight values appears one after another. If applied then happens what explained above.
            while (_serialPort.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
            {                        
                hex += string.Format("{0:X2} ", _serialPort.ReadByte());                        
            }

            byte[] data = FromHex(hex.Trim());
            textBox1.Text = Encoding.ASCII.GetString(data).Trim();
            _serialPort.OnDataReceived-=SerialPortOnDataReceived; // <---add this
        }
    }
}

答案 1 :(得分:0)

这是我更新UI线程的方式。

    delegate void SerialPortOnDataReceivedDelegate(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs);
    private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {
        if (InvokeRequired)
            BeginInvoke(new SerialPortOnDataReceivedDelegate(SerialPortOnDataReceived), new object[] { sender, serialDataReceivedEventArgs });
        else
        {
            if (_serialPort.BytesToRead > 0)
            {
                //hex = "";  <- Without this different weight values appears one after another. If applied then happens what explained above.
                while (_serialPort.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
                {                        
                    hex += string.Format("{0:X2} ", _serialPort.ReadByte());                        
                }

                byte[] data = FromHex(hex.Trim());
                textBox1.Text = Encoding.ASCII.GetString(data).Trim();
            }
        }
    }
    public byte[] FromHex(string aHex)
    {
        aHex = aHex.Replace(" ", "");
        byte[] raw = new byte[aHex.Length / 2];
        for (int i = 0; i < raw.Length; i++)
        {
            raw[i] = Convert.ToByte(aHex.Substring(i * 2, 2), 16);
        }
        return raw;
    }

答案 2 :(得分:0)

这对我有用,我在hex = ""之前加了一些延迟,不过我认为这不是一个好习惯:

        string hex = "";
        private delegate void Closure();        
        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (InvokeRequired)     
            {                
                BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));                
            }
            else
            {
                if (_serialPort.BytesToRead > 0)
                {                    
                    Thread.Sleep(200);  //<-- Add some delay
                    hex = "";

                    while (_serialPort.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
                    {                        
                        hex += string.Format("{0:X2} ", _serialPort.ReadByte());                        
                    }

                    byte[] data = FromHex(hex.Trim());                    
                    textBox1.Text = Encoding.ASCII.GetString(data).Trim();                    
                }
            }
        }