2010-03-24 3 views
3

При использовании асинхронного ввода-вывода (или «перекрытия» ввода-вывода в Win32-жаргоне) нам необходимо иметь дело с структурой OVERLAPPED и его членом hEvent. Если функция ввода-вывода задерживает операцию чтения или записи, мы получим код ошибки ERROR_IO_PENDING, затем мы ожидаем, что асинхронная операция будет завершена с помощью функции WaitForXxxEvent, после чего мы позвоним GetOverlappedResult.hEvent член в OVERLAPPED Структура Win32

Однако, если операция ввода-вывода будет немедленно завершена, мы не получим ERROR_IO_PENDING, и в операции чтения наш буфер чтения будет заполнен немедленно. Но как насчет члена OVERLAPPED::hEvent? Будет ли установлено состояние сигнализации? Я не нашел четкого заявления об этом.

Этот вопрос может показаться бессмысленным (зачем иметь дело с событием, если я знаю, что операция уже завершена?), Однако у меня есть библиотека, которая имитирует перекрывающийся шаблон, и мне нужно иметь то же точное поведение.


Как указан на edgar.holleis в his comment, Raymond Chen объяснил это в своем блоге: http://blogs.msdn.com/b/oldnewthing/archive/2014/02/06/10497096.aspx

Если асинхронный ввод/вывод завершается синхронно, является hEvent в OVERLAPPED структуры сигналом в любом случае?

Да.

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

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

+1

Событие также будет сигнализироваться, если операция завершится немедленно. Он был протестирован с именованными каналами в Windows 7. – bkausbk

ответ

2

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

+0

Это противоречит интуиции ... документация говорит о том, что функции ввода-вывода, принимающие OVERLAPPED, всегда будут перезагружать событие (поэтому нам не нужно вручную перезагружать его перед вызовом) , и что событие будет сообщено, когда операция ввода-вывода будет завершена. Теперь, если операция ввода-вывода завершается немедленно, событие должно быть сообщено, когда функция ввода-вывода вернет TRUE ... hmm ... – Wizard79

+0

Я не собираюсь говорить, что это смутило меня f ** k, но У меня были ОСНОВНЫЕ проблемы с hEvent. В конце концов я просто уволил его и пошел с функцией «WaitForIOCompletion», которая просто спала до ее завершения. – Goz

+3

http://blogs.msdn.com/b/oldnewthing/archive/2014/02/06/10497096.aspx не согласен –

Смежные вопросы