Я работаю с SerialDevice на C ++ / winrt, и мне нужно прослушивать данные, поступающие через порт. Я могу успешно работать с SerialDevice, когда данные передаются через порт, но если ничего не читается, функция DataReader.LoadAsync () зависает, хотя я установил тайм-ауты с помощью SerialDevice.ReadTimeout () и SerialDevice.WriteTimeout (). Итак, чтобы отменить операцию, я использую операцию IAsyncOperation wait_for (), которая истекает через заданный интервал, и я вызываю IAsyncOperation's Cancel () и Close (). Проблема в том, что я больше не могу сделать еще один вызов DataReader.LoadAsync () без исключения take_ownership_from_abi. Как правильно отменить вызов DataReader.LoadAsync (), чтобы разрешить последующие вызовы LoadAsync () для того же объекта?
Чтобы обойти это, я попытался установить тайм-ауты SerialDevice, но это не повлияло на вызовы DataRead.LoadAsync (). Я также попытался использовать create_task с токеном отмены, который также не позволял дополнительный вызов LoadAsync (). Чтобы найти эту статью Кенни Керра, потребовалось много времени: https://kennykerr.ca/2019/06/10/cppwinrt-async-timeouts-made-easy/, где он описывает использование функции wait_for IAsyncOperation.
Вот инициализация SerialDevice и DataReader:
DeviceInformation deviceInfo = devices.GetAt(0);
m_serialDevice = SerialDevice::FromIdAsync(deviceInfo.Id()).get();
m_serialDevice.BaudRate(nBaudRate);
m_serialDevice.DataBits(8);
m_serialDevice.StopBits(SerialStopBitCount::One);
m_serialDevice.Parity(SerialParity::None);
m_serialDevice.ReadTimeout(m_ts);
m_serialDevice.WriteTimeout(m_ts);
m_dataWriter = DataWriter(m_serialDevice.OutputStream());
m_dataReader = DataReader(m_serialDevice.InputStream());
Вот вызов LoadAsync:
AsyncStatus iainfo;
auto async = m_dataReader.LoadAsync(STREAM_SIZE);
try {
auto iainfo = async.wait_for(m_ts);
}
catch (...) {};
if (iainfo != AsyncStatus::Completed)
{
async.Cancel();
async.Close();
return 0;
}
else
{
nBytesRead = async.get();
async.Close();
}
Таким образом, в случае, если AsyncStatus не завершен, вызываются IAsyncOperation Cancel () и Close (), которые согласно документации должны отменить вызов Async, но теперь при последующих вызовах LoadAsync я получаю исключение take_ownership_from_abi. Кто-нибудь знает, что я делаю не так? Почему вообще не работают таймауты SerialDevice? Есть ли лучший способ отменить вызов Async, который позволил бы дальнейшие вызовы без повторной инициализации DataReader? Как правило, кажется, что в пространстве C ++ / winrt очень мало активности, а документации сильно не хватает (даже не нашел метод wait_for примерно до дня пробования других вещей и случайного поиска подсказок в разных сообщениях) - это я что-то упускаю или это действительно так? Спасибо!