Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试关闭串行端口或exí时出现异常;t应用_C#_Multithreading_Serial Communication_Xbee_Real Time Data - Fatal编程技术网

C# 尝试关闭串行端口或exí时出现异常;t应用

C# 尝试关闭串行端口或exí时出现异常;t应用,c#,multithreading,serial-communication,xbee,real-time-data,C#,Multithreading,Serial Communication,Xbee,Real Time Data,我有一个应用程序,通过串口读取XBee帧,并在richtextbox中显示帧。它还在图表中显示2个模拟通道(温度读数),并实时更新 我遇到应用程序读取串行端口的速度快于输入字节的速度的问题,因此我添加了以下行: while (comPort.BytesToRead < (inLength + 4)) Thread.Sleep(10); while(comPort.BytesToRead3) { 组件读取(incByte,0,3); if(incByte[0]==0x7E) { lengt

我有一个应用程序,通过串口读取XBee帧,并在richtextbox中显示帧。它还在图表中显示2个模拟通道(温度读数),并实时更新

我遇到应用程序读取串行端口的速度快于输入字节的速度的问题,因此我添加了以下行:

while (comPort.BytesToRead < (inLength + 4)) Thread.Sleep(10);
while(comPort.BytesToRead<(inLength+4))Thread.Sleep(10);
这解决了这个问题,但现在我无法关闭串行端口或退出应用程序,而没有收到以下消息:“System.dll中发生了类型为'System.InvalidOperationException'的未处理异常附加信息:端口已关闭。”

我怀疑这是一个多线程问题,但如何解决它呢?我在一篇类似的文章中看到,使用BeginInvoke而不是Invoke应该可以解决这个问题,但我已经在使用它了

代码如下:

namespace SerialTest
{
public partial class frmMain : Form
{
    delegate void SetTextCallback(string text);
    delegate void SetChartCallback(double a, double b);

    string inRawFrame = String.Empty;
    double temp1 = 0;
    double temp2 = 0;

    public frmMain()
    {
        InitializeComponent();
    }

    private void btnGetSerialPorts_Click(object sender, EventArgs e)
    {
        if(btnGetSerialPorts.Text == "Open")
        {
            btnGetSerialPorts.Text = "Close";
            comPort.PortName = Convert.ToString(cboPorts.Text);
            comPort.BaudRate = Convert.ToInt32(cboBaudRate.Text);
            comPort.ReadTimeout = 4000;
            comPort.WriteTimeout = 6000;
            if (!comPort.IsOpen)
            {
                try
                {
                    comPort.Open();
                    cboPorts.Enabled = false;
                    cboBaudRate.Enabled = false;
                }
                catch(UnauthorizedAccessException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        else if (btnGetSerialPorts.Text == "Close")
        {
            btnGetSerialPorts.Text = "Open";
            comPort.Close();
            cboPorts.Enabled = true;
            cboBaudRate.Enabled = true;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        string[] arrayComPortsNames = null;
        int index = 0;
        string comPortName = null;

        arrayComPortsNames = SerialPort.GetPortNames();
        Array.Sort(arrayComPortsNames);

        while (!((arrayComPortsNames[index] == comPortName) || (index == arrayComPortsNames.GetUpperBound(0))))
        {
            cboPorts.Items.Add(arrayComPortsNames[index]);
            index++;
        }
        comPortName = arrayComPortsNames[0];
        cboPorts.Text = comPortName;

        cboBaudRate.Items.Add(9600);
        cboBaudRate.Items.Add(14400);
        cboBaudRate.Items.Add(19200);
        cboBaudRate.Items.Add(38400);
        cboBaudRate.Items.Add(57600);
        cboBaudRate.Items.Add(115200);
        cboBaudRate.Items.ToString();
        cboBaudRate.Text = cboBaudRate.Items[5].ToString();
    }

    private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        byte[] incByte = new byte[3];
        int length = 0;

        if(comPort.BytesToRead > 3)
        {
            comPort.Read(incByte, 0, 3);
            if (incByte[0] == 0x7E)
            {
                length = (incByte[1] << 8) + incByte[2];
                byte[] buffer = new byte[length+4];
                buffer[0] = incByte[0];
                buffer[1] = incByte[1];
                buffer[2] = incByte[2];

                ReadFrame(buffer, length, DateTime.Now);
                temp1 = ReadTemp(buffer, 1);
                temp2 = ReadTemp(buffer, 2);
                DisplayFrame();
                UpdateChart();
            }
        }
    }

    private void ReadFrame(byte[] inBuffer, int inLength, DateTime time)
    {
        while (comPort.BytesToRead < (inLength + 4)) Thread.Sleep(10);
        comPort.Read(inBuffer, 3, (inBuffer.Length - 3));

        inRawFrame = time + " " + BitConverter.ToString(inBuffer).Replace("-", " ");
    }

    private void DisplayFrame()
    {

        if (rtbIncomingData.InvokeRequired)
        {
            rtbIncomingData.BeginInvoke(new SetTextCallback(SetText), new object[] { inRawFrame });
        }
        else
        {
            SetText(inRawFrame);
        }
    }

    private void SetText(string text)
    {
        this.rtbIncomingData.AppendText(text + Environment.NewLine);
    }

    private double ReadTemp(byte[] data, int channel)
    {
        if(data[3] == 0x92)
        {
            if(channel == 1)
            {
                return ((((data[19] << 8) + data[20]) * 1.2 / 1023) - 0.5) * 100.0;
            }
            else
            {
                return ((((data[21] << 8) + data[22]) * 1.2 / 1023) - 0.5) * 100.0;
            }
        }
        else
            return 100;
    }

    private void UpdateChart()
    {
        if (chart1.InvokeRequired)
            chart1.BeginInvoke(new SetChartCallback(SetChart), new object[] { temp1, temp2 });
        else
            SetChart(temp1, temp2);
    }

    private void SetChart(double val1, double val2)
    {
        chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Format = "HH:mm:ss";
        chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineColor = Color.LightGray;
        chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineColor = Color.LightGray;
        chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Font = new Font("Consolas", 8);
        chart1.ChartAreas["ChartArea1"].AxisY.LabelStyle.Font = new Font("Consolas", 8);
        chart1.ChartAreas["ChartArea1"].AxisY.Maximum = 30;
        chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 10;
        chart1.ChartAreas["ChartArea1"].AxisY.Interval = 1;
        chart1.Series[0].Name = "Temp 1";
        chart1.Series[1].Name = "Temp 2";
        chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
        chart1.Series[0].MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Diamond;
        chart1.Series[0].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
        chart1.Series[1].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
        chart1.Series[1].MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Diamond;
        chart1.Series[1].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
        chart1.Series[0].Points.AddXY(DateTime.Now, val1);
        chart1.Series[1].Points.AddXY(DateTime.Now, val2);
    }
}
}
namespace序列化测试
{
公共部分类名称:表单
{
委托无效SetTextCallback(字符串文本);
委托无效SetChartCallback(双a,双b);
rawFrame中的字符串=string.Empty;
双temp1=0;
双temp2=0;
公共财政收入()
{
初始化组件();
}
私有void btnGetSerialPorts_单击(对象发送者,事件参数e)
{
如果(btngetserialport.Text==“打开”)
{
btngetserialport.Text=“关闭”;
comPort.PortName=Convert.ToString(cboPorts.Text);
comPort.BaudRate=Convert.ToInt32(cboBaudRate.Text);
comPort.ReadTimeout=4000;
comPort.WriteTimeout=6000;
如果(!comPort.IsOpen)
{
尝试
{
comPort.Open();
cboPorts.Enabled=false;
cbobauddrate.Enabled=false;
}
捕获(未经授权的访问例外)
{
MessageBox.Show(例如Message);
}
}
}
else if(btngetserialport.Text==“关闭”)
{
btngetserialport.Text=“打开”;
comPort.Close();
cboPorts.Enabled=true;
cboBaudRate.Enabled=true;
}
}
私有void Form1\u加载(对象发送方、事件参数e)
{
字符串[]arrayComPortsNames=null;
int指数=0;
字符串comPortName=null;
arrayComPortsNames=SerialPort.GetPortNames();
Array.Sort(arrayComPortsNames);
而(!((arrayComPortsNames[index]==comPortName)| |(index==arrayComPortsNames.GetUpperBound(0)))
{
cboPorts.Items.Add(arrayComPortsNames[索引]);
索引++;
}
comPortName=arrayComPortsNames[0];
cboPorts.Text=comPortName;
cboBaudRate.Items.Add(9600);
CBOBauddrate.Items.Add(14400);
cboBaudRate.Items.Add(19200年);
CBOBauddrate.Items.Add(38400);
cbobudrate.Items.Add(57600);
CBOBauddrate.Items.Add(115200);
cboBaudRate.Items.ToString();
cboBaudRate.Text=cboBaudRate.Items[5].ToString();
}
private void comPort_DataReceived(对象发送方,SerialDataReceivedEventArgs e)
{
SerialPort sp=(SerialPort)发送方;
字节[]incByte=新字节[3];
整数长度=0;
如果(comPort.BytesToRead>3)
{
组件读取(incByte,0,3);
if(incByte[0]==0x7E)
{

length=(incByte[1]如果在
ReadFrame()
仍在等待字节时关闭串行端口,则最终会在关闭的串行端口上检查
BytesToRead
。可能改用此版本:

private void ReadFrame(byte[] inBuffer, int inLength, DateTime time)
{
    while (comPort.IsOpen)
    {
        if (comPort.BytestoRead >= inLength + 4)
        {
            comPort.Read(inBuffer, 3, (inBuffer.Length - 3));
            inRawFrame = time + " " + BitConverter.ToString(inBuffer).Replace("-", " ");
            return;
        }
        Thread.Sleep(10);
    }
}

如果在等待帧时串行端口关闭,它将退出,并且仅在端口仍然打开时检查
BytesToRead

太好了!!完成了。谢谢!!