Я потратил некоторое время на поиск ответа на этот вопрос и нашел много полезной информации в других темах.Я считаю, что написал код таким образом, чтобы он работал, но я не доволен результатом.
Я разработал аппаратную часть, с которой я общаюсь через C #.Аппаратное обеспечение подключается через USB и запускает процедуры инициализации после перечисления с ОС.В этот момент он просто ждет, пока программа C # начнет отправлять команды.В моем коде C # пользователь должен нажать кнопку «Соединить», которая отправит команду и требуемую полезную нагрузку, чтобы дать знать оборудованию, что оно должно продолжать работать.Аппаратное обеспечение затем отправляет команду обратно как ACK.Проблема в том, что моя C # -программа должна ждать получения ACK, но графический интерфейс пользователя полностью заморожен, пока аппаратное обеспечение не ответит, так как я не знаю, как разделить его на другой поток, который может свободно блокироваться.Если аппаратное обеспечение отвечает немедленно, то оно работает нормально, но если оно не может подключиться, то программа остается замороженной на неопределенное время.
С учетом сказанного я знаю, что должно произойти несколько вещей, но я неуверен, как их реализовать.Прежде всего, я не думаю, что сидеть в цикле в ожидании логического значения - это правильный путь, но использование AutoResetEvent на самом деле не кажется намного лучше.Должен быть лучший способ с использованием таймеров, большего количества потоков или чего-то подобного.
Я использую событие DataReceived с объектом serialPort следующим образом:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte cmd = (byte)serialPort1.ReadByte();
if (cmd == (byte)Commands.USB_UART_CMD_MCU_CONNECT)
MCU_Connect_Received.Set();
}
В функции buttonClick («основной» поток), программа останавливается, пока ожидает ACK:
//Send the command to signal a connection
Send_Connection_Packet((byte)Commands.USB_UART_CMD_PC_CONNECT);
textBox1.AppendText("-I- Attempting to contact hardware...");
MCU_Connect_Received.WaitOne();
textBox1.AppendText("Success!" + Environment.NewLine);
В идеале я хотел бы знать, истек ли тайм-аут, чтобы я мог напечатать «Failed!»вместо «Удачи!».Отсутствие тайм-аута также означает, что он останется там навсегда, как я упоминал выше, пока я не убью процесс.Возможно, что он не найдет какое-либо оборудование, но если это произойдет, он должен ответить менее чем за 1 секунду, поэтому таймаута в 2 секунды будет более чем достаточно.Я пытался использовать Thread.Sleep, но это также заморозило графический интерфейс.