Меню

+7 (495) 785-95-25
sale@lcard.ru
sale@lcard.ru
Страницы 1
Тема закрыта
|
||||
|
Обнаружение ошибки в ReadData() из LusbapiИспользуется модуль Е14-440.
Используется потоковый сбор данных с АЦП и асинхронный режим работы функции ReadData, т.е. в поле Overlapped структуры IO_REQUEST_LUSBAPI передается указатель на OVERLAPPED. После вызова ReadData выполняется ожидание с использованием WaitForSingleObject. Проблема состоит в том, что если во время этого ожидания (порядка неск. секунд) произойдет например физическое отключение модуля от USB порта, то WaitForSingleObject сразу же завершится (с результатом 0), а обнаружение ошибки произойдет только при очередном вызове ReadData. В результате (после завершения WaitForSingleObject) имеем не до конца наполненный буфер данных и отсутствие сообщений об ошибке (GetLastErrorInfo возвращает код 100, т.е. все нормально). Вопрос: возможно ли обнаружение таких ошибок в асинхронном режиме работы или это принципиально невозможно ? |
|||
|
||||
|
Re: Обнаружение ошибки в ReadData() из LusbapiВ асинхронном режиме обнаружение ошибок возможно вполне - штатными средствами WinAPI (GetOverlappedResult, GetLastError) См. в руководстве
Когда Вы передаете непустой указатель на структуру OVERLAPPED, работа функции ReadData фактически сводится к вызову WinAPI ReadFile с соответствующими параметрами.
Одного WaitForSingleObject/WaitForMultipleObjects в любом случае недостаточно.
1. В структуре OVERLAPPED hEvent должно быть событие manual reset - результат вызова CreateEvent(NULL, TRUE, FALSE, NULL). Остальные поля нулевые (для устройств). 2. Если ReadFile(...) вернуло TRUE, то операция завершилась сразу (обычно для OVERLAPPED I/O так не бывает, но по документации - имеет право). Тогда берем возвращенное *lpNumberOfBytesRead и
3. Если ReadFile(...) вернуло FALSE, но GetLastError() != ERROR_IO_PENDING, то операция завершилась сразу с ошибкой. 4. Если же ReadFile(...) вернуло FALSE и GetLastError() == ERROR_IO_PENDING, то нужно
5. Делаем WaitForSingleObject с таймаутом, а если нужна возможность прервать работу, например, по команде пользователя, то заводим еще один event для отмены, который можно поднять из другого потока, и:
6. Если сработало событие my_overlapped.hEvent
7. Если вышли по abort_event (case WAIT_OBJECT_0: + 1), по таймауту (case WAIT_TIMEOUT:) или произшла ошибка (default:), то прерываем операцию через CancelIo. После CancelIo ОБЯЗАТЕЛЬНО тоже делать GetOverlappedResult, т.е. следующий шаг не пропускаем. 8. Делаем GetOverlappedResult(hdev, &my_overlapped, &num_bytes, TRUE). По результату завершения этого вызова (TRUE/FALSE и GetLastError) можно судить о том, как завершилась асинхронная операция. Примечание: с момента получения ERROR_IO_PENDING до исполнения GetOverlappedResult с bWait = TRUE нельзя трогать структуру OVERLAPPED, т.к. с ней работает ядро системы. P.S. Вообще по работе с OVERLAPPED I/O существует много руководств, статьи MSDN и темы на форумах, в том числе в нашем форуме, например:
|
Страницы 1
Тема закрыта