Привет, у меня простая связь по последовательному порту, все в соответствии с книгой и документацией, поэтому метод открытого порта выглядит следующим образом:
public SerialPort OpenPort(string portName)
{
Port = new SerialPort(portName, BaudRate);
try
{
Port.Open();
Port.DtrEnable = true;
Port.RtsEnable = true;
Port.DataReceived += DataReceivedEvent;
}
catch (Exception e)
{
Console.WriteLine($"ERRROR: {e.Message}");
}
return Port;
}
Здесь у нас есть событие для чтения данных:
private async void DataReceivedEvent(object sender, SerialDataReceivedEventArgs e)
{
var data = new byte[Port.BytesToRead];
await Port.BaseStream.ReadAsync(data, 0, data.Length);
Response = data;
isFinished = true;
}
Ну, все в порядке, но теперь я хочу отправить сообщение по требованию и сохранить ответ в свойстве, а также добавить токен отмены по таймауту этой задачи.Итак, я придумал этот метод:
public async Task SendMessenge(byte[] messange)
{
var cancellationTokenSource = new CancellationTokenSource();
CancellationToken token = cancellationTokenSource.Token;
cancellationTokenSource.CancelAfter(5000);
token.ThrowIfCancellationRequested();
isFinished = false;
try
{
Task worker = Task.Run(() =>
{
while (!isFinished)
{
}
}, token);
await Port.BaseStream.WriteAsync(messange, 0, messange.Length, token);
await worker;
}
catch (OperationCanceledException e)
{
throw new OperationCanceledException(e.Message, e, token);
}
}
Проблема в том, что цикл while, если это задача, переходит в бесконечный цикл, и он не захватывает токен тайм-аута, если я помещаю его вне задачи иудалить работника это работает, но я теряю токен отмены.Я думаю, что мог бы сделать какой-то ручной обратный отсчет, например:
double WaitTimeout = Timeout + DateAndTime.Now.TimeOfDay.TotalMilliseconds;
while (!(DateAndTime.Now.TimeOfDay.TotalMilliseconds >= WaitTimeout)|| !isFalse)
Но это выглядит ужасно.
Так что я думаю, что мой основной вопрос заключается в том, как эффективно ожидать события от ответа и получить тайм-аут?