A common mistake is to reuse an OVERLAPPED structure before the previous asynchronous operation has been completed. You should use a separate structure for each request.
Ни один приведенный выше пример кода не гарантирует завершения предыдущего завершения асинхронного чтения до нового вызова ReadFile.
Здравствуйте, FDSC, Вы писали:
FDS>Здравствуйте, Alexey Frolov, Вы писали: AF>>Я на 100% не уверен, но такое ощущение что вы читаете с помощью ReadFile порцию, выкидываете ее и ждете следующую. Попробуйте добавить в код следующее и посмотрите что получится
FDS>И что от этого должно измениться?
А то что ожидать окончание операции чтения нужно только если ReadFile вернула ERROR_IO_PENDING, а если функция вернула OK то результат уже в буфере и последующее ожидание приведет к таймауту, а бесконечный цикл который вы привели в примере может вообще привести к зависанию потока.
Моя версия как такое получается: ReadFile возвращает ok, в буфере уже лежит "123", последующий Wait обрывается на таймауте, так как операция завершена (подозреваю что event с автоматическим сбросом), а заново событие уже не просигнализирует. GetOverlappedResult скажет что 0 байт прочитано, такие выводы я сделал прочитав msdn
The results reported by the GetOverlappedResult function are those of the specified handle's last overlapped operation to which the specified OVERLAPPED structure was provided, and for which the operation's results were pending. A pending operation is indicated when the function that started the operation returns FALSE, and the GetLastError function returns ERROR_IO_PENDING. When an I/O operation is pending, the function that started the operation resets the hEvent member of the OVERLAPPED structure to the nonsignaled state. Then when the pending operation has been completed, the system sets the event object to the signaled state.
Specify a manual-reset event object in the OVERLAPPED structure. If an auto-reset event object is used, the event handle must not be specified in any other wait operation in the interval between starting the overlapped operation and the call to GetOverlappedResult. For example, the event object is sometimes specified in one of the wait functions to wait for the operation's completion. When the wait function returns, the system sets an auto-reset event's state to nonsignaled, and a subsequent call to GetOverlappedResult with the bWait parameter set to TRUE causes the function to be blocked indefinitely.
Таким образом возвращаемся к операции чтения читаем следующую порцию "456" ReadFile возвращает ERROR_IO_PENDING. И дальше все идет как задумано. Вот такая у меня версия. Поправьте меня где я не прав и я с удовольствием учту свои ошибки и усвою эту тему
Реальные таймауты чтения записи задаются SetCommTimeout. И при некотором везении WaitForSingleObject никогда не вернет WAIT_TIMEOUT, при том, что новых данных в порту нет.
IMHO:
Если чтение в обработчике оконного сообщения, тогда непонятно что за ReadFile в бесконечном цикле.
Если используете же треды -- то overlapped там нафиг не нужен.
Здравствуйте, gordienkos, Вы писали:
G>Реальные таймауты чтения записи задаются SetCommTimeout. И при некотором везении WaitForSingleObject никогда не вернет WAIT_TIMEOUT, при том, что новых данных в порту нет.
G>IMHO: G>Если чтение в обработчике оконного сообщения, тогда непонятно что за ReadFile в бесконечном цикле. G>Если используете же треды -- то overlapped там нафиг не нужен.
Ну а если мне необходимо использовать таймауты???
Я на 100% не уверен, но такое ощущение что вы читаете с помощью ReadFile порцию, выкидываете ее и ждете следующую. Попробуйте добавить в код следующее и посмотрите что получится
Здравствуйте, Alexey Frolov, Вы писали: AF>Я на 100% не уверен, но такое ощущение что вы читаете с помощью ReadFile порцию, выкидываете ее и ждете следующую. Попробуйте добавить в код следующее и посмотрите что получится
Здравствуйте, Lomion, Вы писали:
L>Всем доброго времени суток!!! L>Вот с такой проблемкой столкнулся...
L>есть что-то такого типа кода:
L>отправитель: L>
Здравствуйте, Lomion, Вы писали:
L>Здравствуйте, gordienkos, Вы писали:
G>>Реальные таймауты чтения записи задаются SetCommTimeout. И при некотором везении WaitForSingleObject никогда не вернет WAIT_TIMEOUT, при том, что новых данных в порту нет.
G>>IMHO: G>>Если чтение в обработчике оконного сообщения, тогда непонятно что за ReadFile в бесконечном цикле. G>>Если используете же треды -- то overlapped там нафиг не нужен. L>Ну а если мне необходимо использовать таймауты???
L>А вообще, из-за чего такая фигня происходит???
Я далеко не гуру, и могу только предполагать.
Асинхронное чтение заканчивается либо когда полностью заполнен выделенный буфер, либо, когда данных нет или недостаточно, то по истечении таймаута, заданного в SetCommTimeout.
В первых двух циклах чтения данные поступают, заполняют трех-байтовый буфер, асинхронное чтение заканчивается до следующего запуска ReadFile.
В третий раз данные не приходят (задержка 1000 в отправителе), WaitForSingleObject возвращает WAIT_TIMEOUT и запускается новая операция чтения, при том что старая вероятно еще не закончена. И дальше начинается цирк...
А при увеличении задержки в WaitForSingleObject, операции чтения разносятся во времени и перестают накладываться друг на дгуга. Это и создает видимость правильной работы.
Здравствуйте, gordienkos, Вы писали:
G>Здравствуйте, Alexey Frolov. G>
G>A common mistake is to reuse an OVERLAPPED structure before the previous asynchronous operation has been completed. You should use a separate structure for each request.
G>Ни один приведенный выше пример кода не гарантирует завершения предыдущего завершения асинхронного чтения до нового вызова ReadFile.
Действительно. Согласен с вами. Пожалуй моя поправка не исправит ситуацию. Вывод: нужно переписать код в соответствии с документацией, там кстати и примеры есть. Самый простой вариант как тут уже говорили non-OVERLAPPED I/O.
Здравствуйте, Alexey Frolov, Вы писали:
AF>Здравствуйте, gordienkos
AF>>...Самый простой вариант как тут уже говорили non-OVERLAPPED I/O. AF>Кстати заметил, вы же это и говорили
Э-э-э-э...
Т. е. надо еще обрабатывать ERROR_IO_INCOMPLETE? или я что-то не понял?
А это будет очень нагло, если я попрошу примерчик накидать?