SerialPort: Ожидание События или получение ответа из потока чтения флуда байтов - C#

Узнай цену своей работы

Формулировка задачи:

Имеется:

OpenPort() - открывает порт и любимый Поток readport() - Поток который считывает всё, всегда и везде lan() - метод который требует ответа, и чтобы все остальное запаузилось, пока не получит ответа main() - запускает все это Источник входящих байтов (ответов) - огромный постоянный нескончаемый поток флуда(т.е. байтов), среди которого требуется получить быстрый и точный ответ на одну операцию. я не знаю, как сделать ожидание ответа (чтобы все остальное запаузилось, пока не получу) в потоке, поэтому решил сделать по-простому: написать в порт и сразу считать из него, запаузив поток чтения.

Проблема:

TimeoutException по абсолютному рандому(50 на 50) я получаю TimeoutException. причем я вижу по Serial Port Monitor'у, что ответ пришел и его считали(раз я увидел, что он пришел). А ГЛАВНОЕ, когда в дебагере прогоняю: ответ ВСЕГДА получаю. таймауты у меня большие сами увидите у меня все подозрения на поток, что он считывает не должное ему. как с ним обойтись? Abort()'ом может? правда доступа к потоку нету, чтобы запустить новый, придется дописывать... или как вообще грамотно организовать всю эту ситуацию?

Вопрос:

возможно ли сделать ожидание события? типо Sleep() в методе lan(), только чтобы разбудить (дождаться ответа) из readport()?
 public void Main()
 {
     Data.stopread = false; //разрешаем потоку считывать байты
     foo[2] = lan; //массив методов. не суть
     OpenPort(); //открывается поток постоянного чтения всего и вся
     foreach (MyDelegate f in foo)
     {
     f();
     }
 }
    public bool OpenPort() // см. Main()
    {            
 
        if (port.IsOpen)
        {
            MessageBox.Show(port.PortName + " уже открыт");
            return false;
        }
        try
        {
            port.Open();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\n(Порт " + port.PortName + " не доступен.");
            return false;
        }
        threadport = new Thread(readport); //вот
        threadport.IsBackground = true;
        threadport.Start();    
 
        return true;
    }
    public void readport()  //поток; см. OpenPort()
    {            
        while (port.IsOpen)
        {
            if (!Data.stopread) //в любой момент можем прикрыть читалку, вроде как?
            {
                Thread.Sleep(500); //каждые пол секунды выдаем, всё, что насобирали
                try
                {
                    if (port.BytesToRead > 0)
                    {
            string hex = "";
                        int gotbytes = port.BytesToRead; 
                       
                        for (int i = 0; i < gotbytes; i++) 
                        {
                            int dec = port.ReadByte();
                            var msg = dec.ToString("X");
                            if (msg.Length < 2) msg = "0" + msg;
                            hex += " " + msg;
                        }
 
                        string answer = Data.pred_answer + hex;
                        if (answer.Length >= 15) //из всего потока байтов выискиваем те, что несут, хоть какой-то смысл
                        {
                            if (find(answer, "64 32 05 DF 4E", hex, out hex)) Invoke(new EventHandler(delegate { textBox1.AppendText("PASS comand" + Environment.NewLine); }));
                            if (find(answer, "64 32 0C 9F CA", hex, out hex)) Invoke(new EventHandler(delegate { textBox1.AppendText("NOT Correct comand" + Environment.NewLine ); }));
                            if (find(answer, "64 32 0B 8F EB", hex, out hex)) Invoke(new EventHandler(delegate { textBox1.AppendText("CRC16 FAILED" + Environment.NewLine ); }));
                        }                       
                        Invoke(new EventHandler(delegate { textBox3.AppendText("TV: " + hex + Environment.NewLine + Environment.NewLine); }));
                    }
                }
                catch (ThreadAbortException) { }   //это исключение появится при аборте
                catch (IOException) { }        
                catch (TimeoutException) { }
                catch (Exception)
                {
                    //continue;
                }
            }
        }
    }
    public bool lan() // см. Main
    {            
    SerialPort port = new SerialPort(); // с ним имеем дело
        Data.stopread = true; //вроде как остановил поток чтения байтов по порту
 
        port.DiscardInBuffer();  //очистил все лишнее, что могло набежать
          
        port.ReadTimeout = 2000; // устанавливаем таймаут
 
        string fail = "11 11 11 11 11 11 11 11 11 11 11";
        string success = "AA AA AA AA AA AA AA AA AA AA AA";
        byte[] answer = new byte[11];
        string str_answer = "";
 
        port.Write(send, 0, send.Length); //послали запрос. не суть
 
        Thread.Sleep(1000); //даем время, чтобы пришли байты/ответ (очень даже много)
 
        try
        {            
            for (int i = 0; i < 11; i++)
            {
                int dec = port.ReadByte(); //читаем первых 11 байт
                var msg = dec.ToString("X");
                if (msg.Length < 2) msg = "0" + msg;
                str_answer += " " + msg;
            }
        }
        catch (TimeoutException)
        {
            txtbox.code_write(" НЕТ ОТВЕТА LAN");
            return false;
        }
 
        // if (str_answer == fail) //deleted
        if (str_answer == success)
        {
            txtbox.code_write("LAN OK");
            Data.stopread = false; //возвращаем поток к жизни - чтению всего и вся (байтов)
            return true;
        }
        txtbox.code_write("LAN: undefined answer");
        Data.stopread = false;  //возвращаем поток к жизни - чтению всего и вся (байтов)           
        return false;
    }

Решение задачи: «SerialPort: Ожидание События или получение ответа из потока чтения флуда байтов»

textual
Листинг программы
var msg = dec.ToString("X2");

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.286 из 5
Похожие ответы