private void buttonComSet_Click(object sender, EventArgs e)
        {
            try
            {
                 //创建接收线程
                ThreadStart readStart = new ThreadStart(ReadThread);
                Thread readThread = new Thread(readStart);                if (flag == false)
                {
                    m_Communication._SerialPort.PortName = this.comboBoxComNum.SelectedItem.ToString();
                    m_Communication._SerialPort.BaudRate = Convert.ToInt32(this.comboBoxBaudRate.SelectedItem.ToString());
                    m_Communication._SerialPort.Open();
                    this.buttonComSet.Text = "关闭串口";
                    flag = true;
                    m_bStartThread = true;
                   
                    readThread.Start();
                }
                else
                {
                    ///终止线程时需要先关闭串口
                    m_Communication._SerialPort.Close();                    m_bStartThread = false;            
                    
                    flag = false;           
                    this.buttonComSet.Text = "打开串口";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
  /// <summary>
        /// 串口接收线程
        /// </summary>
        unsafe private void ReadThread()
        {
            int length = 0;
            byte[] buf = new byte[200];
            String readStr;            while(m_bStartThread)
            {                //同步模式
                length = m_Communication._SerialPort.Read(buf, 0, 200);
           
                if (length > 0)
                {
                    ParseRevData(buf, length);
                }
                else
                {
                    Thread.Sleep(100);
                }
                Thread.Sleep(100);
            }
            
        }
    这两个函数,一个是打开关闭串口、一个是读取串口数据的函数,但是在关闭线程时,报出“由于线程退出或应用程序请求,已放弃I/O操作”;如果使用异步函数ReadExisting()读取数据,会丢失数据!!!那位大哥,给个办法啊,谢谢

解决方案 »

  1.   

     if (readThread != null)
      {
           readThread.Abort()
      }
       m_bStartThread = false;   m_Communication._SerialPort.Close();
      flag = false;//串口状态标记           
      this.buttonComSet.Text = "打开串口";改为这样的顺序,length = m_Communication._SerialPort.Read(buf, 0, 200)还是报出“由于线程退出或应用程序请求,已放弃I/O操作”的错误;
      

  2.   

    read到前半部分,等待后半部分的时候,中断读取操作就会报这个错误。我用ReadLine读取也是这样,只要读到几个字符,直到读到\r,串口都会一直等待读取。
    这个时候关闭串口就会报 IO异常
    (相当于系统告诉你:我读到了一些数据,还没读完整你要求的数据,但是你关闭了串口, Read方法还没有返回,所以读到的这些数据无法保存)。我是用
    try 
    catch
    来解决的,不知道正规的解决方案是什么。
      

  3.   

    如果是退出程序,你可以尝试不关闭串口直接用
    Environment.Exit(0);
    强制回收资源,退出进程。
      

  4.   

    原来你自己写的监听线程,刚没仔细看。
    while(m_bStartThread)
    改为
    while(m_bStartThread && m_Communication._SerialPort.IsOpen)如果还要考虑并发,判断时没关闭,判断后关闭了,那可以考虑
    while(m_bStartThread)
    {
    lock(m_Communication._SerialPort)
    {
    if(!m_Communication._SerialPort.IsOpen) break;
    //你的其他代码
    }
    }