【问题标题】:C# code acts wrong unless debugging除非调试,否则 C# 代码会出错
【发布时间】:2016-11-19 18:48:07
【问题描述】:

所以我一直在研究我的 C# 项目,该项目需要进行一些串行通信。一切正常,直到我遇到了一个非常……奇怪的问题。

所以现在我正在接收存储在 myString 中的串行代码。然后在下面我遇到的问题是,如果我不调试代码,那么整个 if 语句就......被忽略了。但是,当我使用断点时,它一切正常。供参考,除了 (*l) 的部分之外,这里的所有内容都有效 (其余代码因不必要的部分而被删除。如果你们认为有帮助,我可以附上更多。)

public delegate void AddDataDelegate(String myString);
public AddDataDelegate myDelegate;
//
//
this.myDelegate = new AddDataDelegate(AddDataMethod);

//
//
private void Receiver(object sender, SerialDataReceivedEventArgs e) 
{
    Byte[] str = System.Text.Encoding.ASCII.GetBytes(comPort.ReadExisting());

    this.Invoke(this.myDelegate, new Object[] 
    { 
         System.Text.Encoding.Default.GetString(str)
    });

}
//  

private void button2_Click(object sender, EventArgs e)
{
    if (connectionStatus.Text == "Connected")
    {
        comPort.Close();
    }
    else
    {
        try
        {
            comPort.PortName = port;
            comPort.BaudRate = baudRate;
            comPort.DataBits = dataBits;
            comPort.StopBits = (StopBits)stopBits;
            comPort.Parity = parity;
            comPort.DataReceived += new SerialDataReceivedEventHandler(Receiver);

            comPort.Open();
            connectionButton.Text = "Disconnect";
            connectionStatus.Text = "Connected";

        }
        catch
        {
            comPort.Close();
        }
    }
}


public void AddDataMethod(String myString)
{
    try
    {
        string colorSensorValue;
        string distanceSensorValue;
        string proximitySwitch;
        string limitSwitch;
        if (myString.Contains("*c*"))
        {
            string[] colors;
            int red;
            int blue;
            int green;
            int max;
            colorSensorValue = myString.Substring(myString.IndexOf("*c*") + 3);
            if (colorSensorValue.Contains("*e")) colorSensorValue = colorSensorValue.Substring(0, colorSensorValue.IndexOf("*e*"));
            colors = colorSensorValue.Split(',');
            red = Convert.ToInt16(colors[0]);
            green = Convert.ToInt16(colors[1]);
            blue = Convert.ToInt16(colors[2]);

            max = Math.Max(red, Math.Max(green, blue));
            red = red * 255 / max;
            blue = blue * 255 / max;
            green = green * 255 / max;
            color.BackColor = Color.FromArgb(red,blue,green);
            colorSensorTextBox.Text = (colorSensorValue);
        }
        if (myString.Contains("*d"))
        {
            distanceSensorValue = myString.Substring(myString.IndexOf("*d*") + 3);
            if (distanceSensorValue.Contains("*e")) distanceSensorValue = distanceSensorValue.Substring(0, distanceSensorValue.IndexOf("*e*"));
            distanceSensorTextBox.Text = (distanceSensorValue);
        }
        if (myString.Contains("*l"))
        {
            limitSwitch = myString.Substring(myString.IndexOf("*l*") + 3);
            if (limitSwitch.Contains("*e")) limitSwitch = limitSwitch.Substring(0, limitSwitch.IndexOf("*e*"));
            limitRead.Text = limitSwitch;
        }
        if (myString.Contains("*p"))
        {
            proximitySwitch = myString.Substring(myString.IndexOf("*p*") + 3);
            if (proximitySwitch.Contains("*e")) proximitySwitch = proximitySwitch.Substring(0, proximitySwitch.IndexOf("*e*"));
            proximityRead.Text = proximitySwitch;
        }

        comPort.BaseStream.Flush();

    }
    catch
    {

    }

}

myString 示例:

*c*96,84,75*e**d*25.5*e**p*0*e**l*0*e*

所以它将被读作: 颜色: 96 、 84 、 75 (发生正确!) 距离:25.5(发生在正确的位置!) prox : 0 (发生正确!) 限制:0(不会发生..)

请注意,发送和接收数据的顺序不会改变哪个(限制)不起作用,除非我断点

【问题讨论】:

  • 这是某种多线程问题
  • 我如何解决它的任何线索
  • 添加用于接收字符串的代码。你在使用 ReceiveData 事件吗?
  • 输入 System.Diagnostics.Trace.TraceInformation 或登录每个ifs,在 Release 中运行代码(即不是来自 VS)。看看它的行为是否正确。
  • 在发布时运行它一点也不方便,因为我需要进行很多调试。我该怎么做另外两个?详细信息将不胜感激。

标签: c# serial-port serial-communication


【解决方案1】:

根据SerialPort:MSDN中的类信息:

数据接收时在辅助线程上引发 DataReceived 事件 从 SerialPort 对象接收。因为这个事件是在一个 辅助线程,而不是主线程,试图修改一些 主线程中的元素,例如 UI 元素,可能会引发 线程异常。如果需要修改 main 中的元素 表单或控件,使用 Invoke 将更改请求发布回来,这样就可以了 在正确的线程上工作。

你应该使用这种形式:

this.Invoke(this.AddDataMethod, new Object[] { The_Received_String });
                    }

【讨论】:

  • 所以我只是在该部分添加“.Parent”?
  • 对不起,我复制并粘贴了我的代码。我有一个通用串行类。
  • 奇怪的是,即使我更改了 IF 语句的顺序,它也只会跳过特定的 IF。感谢您的尝试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
相关资源
最近更新 更多