Элемент hEvent в структуре OVERLAPPED Win32

Когда используется асинхронный ввод-вывод (или «перекрывающийся» ввод-вывод на жаргоне 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 в любом случае?

да.

Когда ввод-вывод завершается (синхронно или асинхронно), о событии сигнализируется, и уведомления о состоянии завершения помещаются в очередь. Функцию Get­Overlapped­Result/Ex можно использовать для ожидания уже завершенного ввода-вывода; он просто вернется немедленно. Если вы спросите у HasOverlappedIoCompleted, завершился ли ввод-вывод и завершился ли ввод-вывод синхронно, он правильно сообщит: «Да, конечно, он завершен. Черт возьми, он завершен давным-давно!»

Другими словами, вы можете логически рассматривать случай синхронного выполнения асинхронного запроса ввода-вывода, как если бы он был завершен асинхронно. Он просто завершается асинхронно, прежде чем вы даже моргнули.


person lornova    schedule 24.03.2010    source источник
comment
Событие также будет сигнализировано, если операция завершится немедленно. Он был протестирован с именованными каналами в Windows 7.   -  person bkausbk    schedule 06.06.2012


Ответы (1)


Нет, не будет. Мне понадобилась целая вечность, чтобы понять это на собственном горьком опыте ;)

person Goz    schedule 24.03.2010
comment
Это нелогично... в документации сказано, что функции ввода-вывода, которые принимают OVERLAPPED, всегда будут сбрасывать событие (поэтому нам не нужно сбрасывать его вручную перед вызовом), и что событие будет сигнализироваться, когда I /O операция будет завершена. Теперь, если операция ввода-вывода завершается немедленно, событие должно быть сигнализировано, когда функция ввода-вывода возвращает TRUE... хм... - person lornova; 25.03.2010
comment
Я не собираюсь говорить, что это сбило меня с толку, но у меня были ОСНОВНЫЕ проблемы с hEvent. В конце концов, я просто уволил его и перешел к функции WaitForIOCompletion, которая просто спит, пока не завершится. - person Goz; 29.03.2010
comment
@edgar.holleis спасибо, вы должны добавить это как полный ответ - person lornova; 15.10.2015