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");
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д