程序如下,电脑发下去之后,设备马上有返回,但是我的接收事件要等很久才能收到,高手指点using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Threading;namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        SerialPort SP1 = new SerialPort();
        List<string> xieyi = new List<string>();        public Form1()
        {            InitializeComponent();
            SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
        
        }                private void Form1_Load(object sender, EventArgs e)
        {
            string rdline;
            int i;
            comboBox1.SelectedItem=comboBox1.Items[0];
            comboBox2.SelectedItem = comboBox2.Items[0];            try
            {
                FileStream sFile = new FileStream(".\\d645.txt", FileMode.Open);
                StreamReader sr = new StreamReader(sFile);                rdline = sr.ReadLine();
                while(rdline!=null)
                {
                xieyi.Add(rdline);
                rdline = sr.ReadLine();
                }                label1.Text = xieyi[0];                for (i=1;i<xieyi.Count;i++)
                {
                    checkedListBox1.Items.Add(xieyi[i].Substring(0,4));
                    checkedListBox1.SetItemChecked(i-1, true);                }            }
            catch (Exception ee)
            {
                MessageBox.Show("加载文件失败:"+ee);
            }
            
        }        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
            
            SP1.PortName = comboBox1.SelectedItem.ToString();
            SP1.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
            SP1.Parity = Parity.Even;            SP1.ReceivedBytesThreshold = 1;
                SP1.Open();
            }
            catch (Exception ee) { MessageBox.Show(comboBox1.SelectedItem.ToString() + "失败:"+ee); }
            
        }        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {        }        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {        }        private void button2_Click(object sender, EventArgs e)
        {        }        private void label2_Click(object sender, EventArgs e)
        {        }        private void button2_Click_1(object sender, EventArgs e)
        {
        int i=0;
        while (checkedListBox1.GetItemChecked(i))
        {
            string s = xieyi[i+1];
            int len = s.Length / 2;
            byte[] bytes = new byte[len];
            for (int j = 0; j < len; j++)
            {
                bytes[j] = Convert.ToByte((s.Substring(j * 2, 2)), 16);
            }
            
            try
            {
                SP1.Write(bytes, 0, len);
            }
            catch (Exception ee) { MessageBox.Show(comboBox1.SelectedItem.ToString() + "失败:" + ee); }
            Thread.Sleep(1000);
            richTextBox1.Text += "\r\n";            i++;
            if (i >= checkedListBox1.Items.Count)
                break;        }
        }        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {            string tmpstr = "";
            for (int i = 0; i < SP1.BytesToRead; i++)
            {
                tmpstr += Convert.ToString(SP1.ReadByte(), 16) + " ";            }
            safeAddtrText(tmpstr);
        }        public delegate void _SafeAddtrTextCall(string text);        private void safeAddtrText(string text)
        {
            if (this.InvokeRequired)
            {
                _SafeAddtrTextCall call =
                delegate(string s)
                {
                    richTextBox1.Text += s;
                };                this.Invoke(call, text);
            }
            else
            {
                richTextBox1.Text += text;            }
        }        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {        }    }
}

解决方案 »

  1.   

    可以设置serialport的ReadBufferSize 和WriteBufferSize 属性来改变缓冲大小,
      

  2.   

    1。检查波特率、奇偶校验等两边是否一致。
    2。DataReceived方法越快越好(慢的话会导致缓冲区中的待读数据越来越多,最后溢出),所以最好把Invoke改成BeginInvoke,防止长时间同步等待UI线程更新界面。
    3。DataReceived中的for循环:for (int i = 0; i < SP1.BytesToRead; i++),应把SP1.BytesToRead提到循环外:int bytesToRead = SP1.BytesToRead; 这样缓冲区中有多个数据时才能正确执行。
    4。发送过程中不要用Thread.Sleep(1000); 这样会阻塞UI线程(当此时有接收数据到达,会因为要更新界面而被迫等待1秒),改成循环Application.DoEvents(); 并在循环中判断等待的时间是否超过1秒。
      

  3.   


    读取数据时,先sleep(100);
      

  4.   

    2。DataReceived方法越快越好(慢的话会导致缓冲区中的待读数据越来越多,最后溢出),所以最好把Invoke改成BeginInvoke,防止长时间同步等待UI线程更新界面。4。发送过程中不要用Thread.Sleep(1000); 这样会阻塞UI线程(当此时有接收数据到达,会因为要更新界面而被迫等待1秒),改成循环Application.DoEvents(); 并在循环中判断等待的时间是否超过1秒。能不能帮我改下这2点
      

  5.   

    现在把
    Thread.Sleep(1000);
    改成
    for (int q = 0; q < 1000000; q++)
                {
                    Application.DoEvents();
                }
    但是最后一个字节老是出不来,必须要发下条指令的时候才能出现上条返回指令的最后一个字节
      

  6.   


     string tmpstr = "";
      for (int i = 0; i < SP1.BytesToRead; i++)
      {
      tmpstr += Convert.ToString(SP1.ReadByte(), 16) + " ";  }
    再者,用string拼接效率极低,尤其是byte的拼接,
    你就算要用这个方法,也得用stringbuilder,效率会提高不少.
     byte[] readBuffer = new byte[comport.ReadBufferSize];
                        int bytLength = comport.Read(readBuffer, 0, comport.ReadBufferSize);
                        string msgRec = myEncode.GetString(readBuffer, 0, bytLength);//接收到的信息
      

  7.   


     private void comPort_DataReceiveed(object sender, SerialDataReceivedEventArgs e)
            {
                if (bClosing)
                {
                    return;
                }
                try
                {
                    bListening = true;
                    int n = comPort.BytesToRead;
                    byte[] receiveByte = new byte[n];
                    comPort.Read(receiveByte, 0, n);
                    AddItemToListBox(receiveByte);
                    ReceiveCount += n;
                    ChangStatus("接收成功!");
                }
                finally
                {
                    bListening = false;
                }
            }
      

  8.   

    现在把
    Thread.Sleep(1000);
    改成
    for (int q = 0; q < 1000000; q++)
      {
      Application.DoEvents();
      }
    现在发送马上有返回
    但是最后一个字节老是出不来,必须要发下条指令的时候才能出现上条返回指令的最后一个字节
      

  9.   

    在for循环中,SP1.BytesToRead是不断变化的,每次调用ReadByte(),BytesToRead就会减1,
    所以如果缓冲区有2个以上数据的时候,你的循环方式就读不到后面的数据。byte[] readBuffer = new byte[SP.BytesToRead];
    int byteLength = SP.Read(readBuffer, 0, SP.BytesToRead);
    tmpstr = BitConverter.ToString(readBuffer).Replace('-', ' ');
      

  10.   

    我想每个字节一个空格,但是现在是返回的数据是 2个字节一个空格
    FEFE FEFE 6800 0000 0000 0068 8116 52C3 3333 3333 3333 3333 3333 3333 3333 3333 3333 3333 7816
    FEFE FEFE 6800 0000 0000 0068 8116 52C3 3333 3333 3333 3333 3333 3333 3333 3333 3333 3333 7816
      

  11.   

    tmpstr = readBuffer.Aggregate("", (s, b) => s+b.ToString("x")+ ' ');
      

  12.   

    SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    SP1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    多写几次,就可以了。我试过。
    最好采用接收线程来接收数据。