Когда используется асинхронный ввод-вывод (или «перекрывающийся» ввод-вывод в жаргоне Win32), нам нужно иметь дело со структурой OVERLAPPED
и его hEvent
членом. Если функция ввода-вывода задержит операцию чтения или записи, мы получим код ошибки ERROR_IO_PENDING
, затем дождемся завершения асинхронной операции с функцией WaitForXxxEvent
, затем мы вызовем GetOverlappedResult
.
Однако, если операция ввода-вывода будет немедленно завершена, мы не получим ERROR_IO_PENDING
, и в операции чтения наш буфер чтения будет немедленно заполнен. Но как насчет члена OVERLAPPED::hEvent
? Будет ли он установлен в сигнальное состояние? Я не нашел четкого заявления об этом.
Этот вопрос может показаться бессмысленным (зачем иметь дело с событием, если я знаю, что операция уже завершена?), Однако у меня есть библиотека, которая имитирует перекрывающийся шаблон, и мне нужно точно такое же поведение.
Как указал edgar.holleis в своем комментарии , Раймонд Чен объяснил это в своем блоге: http://blogs.msdn.com/b/oldnewthing/archive/2014/02/06/10497096.aspx
Если асинхронный ввод-вывод завершается синхронно, сигнализирует ли hEvent в структуре OVERLAPPED в любом случае?
Да.
Когда ввод / вывод завершается (синхронно или асинхронно),
событие сигнализируется и уведомления о завершении состояния ставятся в очередь.
GetOverlappedResult/Ex
функция может быть использована для ожидания ввода / вывода, который
уже завершено; это просто вернется немедленно. Если вы спросите
HasOverlappedIoCompleted, завершен ли ввод-вывод, и ввод-вывод
завершено синхронно, он правильно сообщит: «Да, конечно
завершено. Черт возьми, это закончено давным-давно! "
Другими словами, вы можете логически рассматривать случай асинхронного
Запрос ввода / вывода выполняется синхронно, как если бы он был выполнен
асинхронно. Это просто завершается асинхронно, прежде чем вы даже
моргнула.