Я считаю, что проблема с драйвером, который обслуживает COM-порт.Следовательно, не будет API для «фактического закрытия» COM-порта.
Кстати, после закрытия дескриптора файла не нужно ждать завершения всех выдающихся операций ввода-вывода с ошибками.Когда CloseHandle
возвращает все ожидающие операции ввода-вывода уже завершено / отменено, вы просто получаете обратные вызовы асинхронно (будь то через порт завершения или очередь APC, неважно).
В частности, драйверы FTDI (те, которые эмулируют COM-> USB), как известно, очень сбивают с толку.
Я могу только рекомендовать попробовать сброс данных перед закрытием ручки.Вы можете подождать, пока все операции ввода-вывода завершат , прежде чем закроет COM-порт (если это применимо для вашего случая).В качестве альтернативы вы можете позвонить SetCommMask
и WaitCommEvent
, чтобы убедиться в отсутствии ожидающих отправки данных.Надеемся, что это может помочь.
РЕДАКТИРОВАТЬ:
Немедленно (до возвращения) CloseHandle
отменяет все ожидающие операции ввода-вывода для дескриптора файла?
Строго говоря - нет .
Могут быть и другие ссылки на файловый объект.Например, код режима пользователя может вызвать DuplicateHandle
, или драйвер режима ядра может вызвать ObReferenceObjectByXXXX
.В таком случае объект, на который ссылается дескриптор, не обязательно освобождается.
Когда последний дескриптор закрыт, вызывается драйвер DispatchCleanup
.Он должен отменить все ожидающие операции ввода-вывода в соответствии с this .
Однако, пока один поток находится в пределах CloseHandle
- теоретически вы можете выполнить другой ввод-вывод из другого потока (если выповезло - ручка все равно будет в силе).Во время вызова функции ввода-вывода (например, WriteFile
или т. Д.) ОС временно увеличивает счетчик ссылок на объект.Это, в свою очередь, может запустить другой ввод / вывод, который не будет отменен напрямую с помощью вызова CloseHandle
.
Однако в этом случае дескриптор будет закрыт O / S сразу после нового ввода / вывода.O выдан, потому что счетчик ссылок на объект снова достиг 0. 0. 1041 *
Так что в таком извращенном сценарии может возникнуть ситуация, когда сразу после вызова CloseHandle
вы не сможете открыть файл заново.еще раз.