serialport отвечает на EventHandler, но не ReadExisting или ReadLine?

У меня есть программа, которая читает из последовательного порта в c#. мне нужно быстро записать в порт, прочитать из него, затем закрыть его. я не могу оставить его открытым. я понимаю, что последовательные порты читают и пишут медленно, Я пытался установить свойства ReadTimeout и WriteTimeout высокими, и добавил поток. Sleep, чтобы попытаться растянуть время чтения и записи для устройств. вот немного кода:

мой метод для записи в порт:

    private void CheckPorts(string testMessage)
    {

        foreach (string s in SerialPort.GetPortNames())
        {
            portNumber = Int32.Parse(s.Remove(0, 3));
            testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
            if (testSerial.IsOpen)
            {
                testSerial.Close();
            }
            testSerial.ReadTimeout = 2000;
            testSerial.WriteTimeout = 1000;
            testSerial.Open();
            if (testSerial.IsOpen)
            {
                string received;
                testSerial.DiscardInBuffer();
                try
                {
                    //testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);

                    testSerial.Write(testMessage);
                    System.Threading.Thread.Sleep(2000);

                    received = testSerial.ReadExisting();  //EITHER I USE THIS OR EVENT HANDLER, NOT BOTH
                }
                catch (TimeoutException e)
                {
                    testSerial.Close();
                    continue;
                }

               if (received.Length > 0)
                {
                    MessageReceived(received);
                }
                testSerial.Close();
            }
       } 
 }



 private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        string received = testSerial.ReadExisting();
        int y = received.IndexOf("\r");
        while (y == -1)
        {
            received = received + testSerial.ReadExisting();
            y = received.IndexOf("\r");
        }

        if (testSerial.IsOpen)
        {
            testSerial.Close();
        }

    }

мне интересно, если мне обязательно нужно использовать datahandler, как мне держать последовательный порт открытым достаточно долго, чтобы читать с него, но закрыть последовательный порт до того, как нужно будет открыть следующий порт?

Видите ли, первый метод вызывается несколько раз, и он проходит через цикл foreach, пробуя сообщение на нескольких портах, затем пытаясь прочитать ответ. Поэтому в какой-то момент я должен закрыть порты, иначе в следующий раз, когда он пройдет через них, он не будет работать должным образом, потому что порт все еще открыт

Вот мой обновленный код (все еще не работает):

 private void CheckPorts(string testMessage, int baudRate)
    {

        foreach (string s in SerialPort.GetPortNames())
        {
            var interval = 3000; // ms 
            var timer = new System.Timers.Timer(interval);
            timer.Elapsed += (o, e) =>
            {
                timer.Enabled = false;

                if (testSerial.IsOpen)
                    testSerial.Close();  // may not be necessary with Dispose? 

                testSerial.Dispose();
                timer.Dispose();
            };

            portNumber = Int32.Parse(s.Remove(0, 3));
            testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
            testSerial.ReadTimeout = 2000;
            testSerial.WriteTimeout = 2000;
            if (testSerial.IsOpen)
            {
                testSerial.Close();
            }

            testSerial.Open();
            timer.Enabled = true; 

            if (testSerial.IsOpen)
            {
                string received;
                //testSerial.DiscardInBuffer();
                //autoEvent = new AutoResetEvent(false);
                try
                {
                   // testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);

                  // autoEvent.Reset();
                    lblPortNum.Content = s;
                    lblPortNum.Refresh();

                    testSerial.Write(testMessage);
                    //System.Threading.Thread.Sleep(2000);

                    //testSerial.NewLine = "\r\n";
                    byte[] rBuff = new byte[2];
                    int rCnt = testSerial.Read(rBuff, 0, 2);
                    System.Text.Encoding enc = System.Text.Encoding.ASCII;
                    received = enc.GetString(rBuff);



                     //received = testSerial.ReadLine();
                }
                catch (TimeoutException e)
                {
                    testSerial.Close();
                    continue;
                }

               if (received.Length > 0)
               {
                    MessageReceived(received, Int16.Parse(s.Remove(0, 3)));
                }
                /*
                if (autoEvent.WaitOne(2000))
                {
                    // the port responded 
                   // testSerial.Close();
                    autoEvent.Dispose();
                    lblPortNum.Content = "HEY I RESPONDED";
                }
                else
                {
                    testSerial.Close();
                    autoEvent.Dispose();
                    continue;
                    // port did not respond within 2 seconds 
                }*/
              //testSerial.Close();
            }
        } 
     }

ОБНОВИЛСЯ Снова (все еще не работает должным образом)

private void CheckPorts(string testMessage, int baudRate)
    {

        foreach (string s in SerialPort.GetPortNames())
        {
            portNumber = Int32.Parse(s.Remove(0, 3));

            // MUST BE LOCAL 
            var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
            serialOneOfMany.ReadTimeout = 2000;
            serialOneOfMany.WriteTimeout = 2000;
            if (serialOneOfMany.IsOpen)
            {
                serialOneOfMany.Close();
            }

            // timer must be defined _after_ serialOneOfMany 
            var interval = 3000; // ms  
            var timer = new System.Timers.Timer(interval);
            timer.Elapsed += (o, e) =>
            {
                timer.Enabled = false;

                if (serialOneOfMany.IsOpen)
                    serialOneOfMany.Close();  // may not be necessary with Dispose?  

                serialOneOfMany.Dispose();
                timer.Dispose();
            };

            if (serialOneOfMany.IsOpen)
            {
                string received;

                try
                {
                    lblPortNum.Content = s;
                    lblPortNum.Refresh();

                    serialOneOfMany.Write(testMessage);
                    byte[] rBuff = new byte[2];
                    int rCnt = serialOneOfMany.Read(rBuff, 0, 2);
                    System.Text.Encoding enc = System.Text.Encoding.ASCII;
                    received = enc.GetString(rBuff);

                }
                catch (TimeoutException e)
                {
                    serialOneOfMany.Close();
                    continue;
                }

                if (received.Length > 0)
                {
                    CheckIfTheMessageMatches(received, Int16.Parse(s.Remove(0, 3)));
                }

            }
        } 

    }

так что с этим обновлением он просто прорывается через код, я могу пройти по коду строка за строкой, но он не останавливается на 3 секунды вообще. Если я запускаю его без перерывов на отладку, он просто проходит через него за долю секунды

ОБНОВЛЕНИЕ 10-25-11

 private void CheckPorts(string testMessage, int baudRate)
    {
        foreach (string s in SerialPort.GetPortNames())
        {
            string received = "";
            testSerial = new SerialPort(s,baudRate, Parity.None, 8, StopBits.One);

            lblStatus.Content = "Scanning...";
            lblStatus.Refresh();

            if (testSerial.IsOpen)
            {
                testSerial.Close();
            }
            else
            {
                testSerial.Open();
            }

            if (testSerial.IsOpen)
            {
                try
                {
                    testSerial.NewLine = "\r";
                    lblPortNum.Content = s;
                    lblPortNum.Refresh();
                    testSerial.WriteTimeout= 500;
                    testSerial.ReadTimeout = 1000;
                    testSerial.WriteLine(testMessage);

                    System.Threading.Thread.Sleep(500);

                    /*THIS DOESN'T WORK
                    byte[] buffer = new byte[testSerial.BytesToRead];
                    int rCnt = testSerial.Read(buffer, 0, buffer.Length);
                    received = enc.GetString(buffer);*/

                    //received = Convert.ToString(testSerial.BaseStream.Read(buffer, 0, (int)buffer.Length));


                    received =  testSerial.ReadLine();


                   int y = received.IndexOf("\r");
                   while (y == -1)
                   {
                       received = received + testSerial.ReadExisting();
                       y = received.Length;
                   }

                   if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
                   {
                       CheckIfTheMessageMatches(received, s);
                       received = received + lblInfo.Content;
                       lblInfo.Content = received;
                   }
                   else
                   {
                       lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
                   }
                   if (testSerial.IsOpen)
                   {
                       testSerial.Close();
                   }

                    /*I USE THIS WITH THE sPort.Read() METHOD
                    while (rCnt > 0)
                    {
                        if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
                        {
                            CheckIfTheMessageMatches(received, s);
                            rCnt = 0;
                            received = received + lblInfo.Content;
                            lblInfo.Content = received;                                
                        }

                        else
                        {
                            lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
                        }
                    }
                     */

                   if (testSerial.IsOpen)
                   {
                       testSerial.Close();
                   }

                }
                catch (TimeoutException e)
                {
                    testSerial.Close();
                    continue;
                }
                received = null;
            }
        } 

        lblStatus.Content = "Finished Scanning.";
        lblPortNum.Content = "";
    }

ОБНОВЛЕННЫЙ КОД вот новый код, все еще не работает, dataeventhandler даже не вызван ни разу. я знаю, что он получает сообщения, потому что у меня есть другая программа, которая работает с последовательными устройствами

private void CheckPorts(string testMessage, int baudRate)
    {
        foreach (string s in SerialPort.GetPortNames())
        {
            var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
            serialOneOfMany.ReadTimeout = 700;
            serialOneOfMany.WriteTimeout = 100;

            var interval = 500; // ms
            var timer = new System.Timers.Timer(interval);
            timer.Elapsed += (o, e) =>
            {
                timer.Enabled = false;

                if (serialOneOfMany.IsOpen)
                    serialOneOfMany.Close();  // may not be necessary with Dispose?

                serialOneOfMany.Dispose();
                timer.Dispose();
            };
            timer.Enabled = true;

            lblStatus.Content = "Scanning...";
            lblStatus.Refresh();

            if (serialOneOfMany.IsOpen)
            {
                serialOneOfMany.Close();
            }
            else
            {
                serialOneOfMany.Open();
            }

            if (serialOneOfMany.IsOpen)
            {
                string received;

                try
                {
                    lblPortNum.Content = s;
                    lblPortNum.Refresh();

                    serialOneOfMany.WriteLine(testMessage);
                    System.Threading.Thread.Sleep(400);
                    serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);

                }
                catch (TimeoutException e)
                {
                    serialOneOfMany.Close();
                    continue;
                }
            }
        } 

        lblStatus.Content = "Finished Scanning.";
        lblPortNum.Content = "";
    }

    private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort receivingSerial = sender as SerialPort;
        string received = receivingSerial.ReadExisting();
        int y = received.IndexOf("\r");
        while (y == -1)
        {
            received = received + receivingSerial.ReadExisting();
            y = received.IndexOf("\r");
        }

        if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
        {
            string name = receivingSerial.PortName;
            received = received + lblInfo.Content;
            lblInfo.Content = received;
            CheckIfTheMessageMatches(received, name);
        }
        else
        {
            lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
        } 
        if (receivingSerial.IsOpen)
        {
            receivingSerial.Close();
        }

    }
5
задан John Saunders 15 November 2012 в 07:52
поделиться