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");