C# 尝试在UI线程中设置变量

C# 尝试在UI线程中设置变量,c#,multithreading,serial-port,C#,Multithreading,Serial Port,我使用此代码从称重秤读取重量值,我成功地从中读取重量值,但当尝试为下一个重量值设置变量hex=”“时,我无法在文本框中获取它,它会很快出现,然后再次消失,如果我使用hex=”“启用跟踪程序,结果与预期一致,但是如果运行程序而不跟踪它,那么闪烁的值和文本框将变为空:(有什么想法吗 string hex = ""; private delegate void Closure(); private void SerialPortOnDataReceive

我使用此代码从称重秤读取重量值,我成功地从中读取重量值,但当尝试为下一个重量值设置变量
hex=”“
时,我无法在文本框中获取它,它会很快出现,然后再次消失,如果我使用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)
                {
                    //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;
        }
string hex=”“;
私有委托无效闭包();
私有void SerialPortOnDataReceived(对象发送方,SerialDataReceivedEventArgs SerialDataReceivedEventArgs)
{
如果(需要调用)
{                
BeginInvoke(新闭包(()=>{SerialPortOnDataReceived(sender,serialDataReceivedEventArgs);}));
}
其他的
{
如果(_serialPort.BytesToRead>0)
{

//hex=“”;0)//在按下打印键时调用的方法中,可以添加串行端口事件处理程序:

_serialPort.OnDataReceived+=SerialPortOnDataReceived;
然后,在
SerialPortOnDataReceived
方法的末尾(成功读取后),从串行端口对象中删除事件处理程序。这将使它停止侦听串行端口上的新数据,直到再次按print

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
        }
    }
}
private void SerialPortOnDataReceived(对象发送方,SerialDataReceivedEventArgs SerialDataReceivedEventArgs)
{
如果(需要调用)
{                
BeginInvoke(新闭包(()=>{SerialPortOnDataReceived(sender,serialDataReceivedEventArgs);}));
}
其他的
{
如果(_serialPort.BytesToRead>0)
{

//hex=“”;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;
    }
委托无效SerialPortOnDataReceivedDelegate(对象发送方,SerialDataReceivedEventArgs SerialDataReceivedEventArgs);
私有void SerialPortOnDataReceived(对象发送方,SerialDataReceivedEventArgs SerialDataReceivedEventArgs)
{
如果(需要调用)
BeginInvoke(新SerialPortOnDataReceivedElegate(SerialPortOnDataReceived),新对象[]{sender,serialDataReceivedEventArgs});
其他的
{
如果(_serialPort.BytesToRead>0)
{

//hex=“”;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();                    
                }
            }
        }
string hex=”“;
私有委托无效闭包();
私有void SerialPortOnDataReceived(对象发送方,SerialDataReceivedEventArgs SerialDataReceivedEventArgs)
{
如果(需要调用)
{                
BeginInvoke(新闭包(()=>{SerialPortOnDataReceived(sender,serialDataReceivedEventArgs);}));
}
其他的
{
如果(_serialPort.BytesToRead>0)
{                    

Thread.Sleep(200);//0)//您希望发生什么?当您没有hex=“”时,它只是显示不同的权重值闪烁;每次接收到串行数据时,它都会显示一个新值。当您添加该行时,它将(同样快地)显示出来每次接收到更多数据时,请清除接收到的数据。如果您只想接收一次权重值,则可以在触发一次事件后删除事件处理程序。我只想在每次按权重标尺中的
打印
键时只接收一个权重值。请查看上面编辑的代码,我按照您的指示做了要执行,并继续执行相同的操作。一个度量值显示在另一个度量值的旁边。您是否也将该行添加到
SerialPortOnDataReceived
方法中?我刚刚首先添加了
\u serialPort.DataReceived-=SerialPortOnDataReceived;
,您告诉我,当按
打印时,文本框中的结果只有零,然后我添加了t他
\u serialPort.DataReceived+=SerialPortOnDataReceived;
在方法的开头,文本框中显示其他开头旁边的一个度量值。您可以发布按钮单击和事件处理程序方法的当前代码吗?它们已经发布。第一个是事件处理程序方法,第二个是按钮click、 Dmitri,与您的方法相同的结果,请参见上图。您是否可以选择让数字改变,直到它们停止输入?有点像实际的刻度,当您踏上它并进行计算时。似乎刻度在线程之后停止向您发送值。睡眠(200)你可能不会得到最准确的结果。如果“最好”呢结果是最后一个发送的结果?只是需要考虑一下。问题是,当我准备获取重量值时,我按下“打印”按钮,到那时,秤的重量是正确的。明白了。我唯一能想到的是,你是否会添加一个if语句来检查textBox1。Text是“”如果是,则添加值;如果不是,则不执行任何操作。然后在按钮单击事件中将其设置回“”。
        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();                    
                }
            }
        }