WinAPI Ожидание в канале для чтения данных

Я пишу программу для чтения и записи в каналы. Я обнаружил, что с помощью функции PeekNamedPipe я могу получить количество байтов, готовых к чтению. Но у меня вопрос Как я могу дождаться прихода данных. Могу ли я использовать функцию WaitForSingleObject для ожидания в канале получения данных с другого конца канала. С уважением,


person MrDoDo    schedule 05.11.2013    source источник
comment
Какое ожидание вам нужно? Если вы выполняете обычное чтение, оно уже будет ждать (блокироваться), пока не будет доступно достаточное количество байтов.   -  person MSalters    schedule 05.11.2013
comment
Я хочу прочитать все доступные данные (количество байтов, которое возвращает PeekNamedPipe), и после этого буду ждать, а после поступления данных повторю это.   -  person MrDoDo    schedule 05.11.2013


Ответы (1)


Вы можете использовать Overlapped I/ O или предпочтительно используйте Процедуры завершения. Они оба являются асинхронными (неблокирующими), но я предпочитаю подпрограммы завершения, поскольку вы регистрируете обратный вызов, который вызывается, когда есть данные для чтения - нет необходимости опрашивать данные. Просмотрите ссылки, создайте и запустите примеры. Это может занять некоторое время, чтобы понять / внедрить, но вы будете рады, что потратили это время, чтобы сделать это правильно, когда оно работает хорошо :).

person parrowdice    schedule 05.11.2013
comment
Я предпочитаю перекрывающийся ввод-вывод. Обычно в моем канале связи у меня есть несколько событий, таких как выключение, определенные действия и событие для перекрывающегося ввода-вывода, которое я использую для ожидания. В зависимости от протокола, который я использую, у меня обычно есть заголовок. Я прочитал заголовок с перекрывающимся вводом-выводом. Когда у меня есть заголовок, я читаю завершающий блок сообщений с блокирующим ReadFile... - person xMRi; 05.11.2013
comment
@xMRi: То, что вы описали, можно сделать с помощью процедур завершения, но, на мой взгляд, это проще. Кроме того, если вы используете перекрывающийся ввод-вывод, почему вы используете блокирующий вызов? Разве это не противоречит подходу Overlapped? - person parrowdice; 05.11.2013
comment
Отправитель записывает полное сообщение (включая заголовок) в канал. После того, как я прочитал заголовок (с неблокирующим вызовом), я знаю длину остатка и могу прочитать его без блокировки. - person xMRi; 05.11.2013
comment
@xMRi: Хорошо, я вижу, что это может быть выгодно, если вы используете канал PIPE_TYPE_BYTE. Как я уже упоминал в ответе, любой из них является хорошим подходом, я думаю, главное, что нужно сделать, это использовать асинхронный метод и выбрать реализацию, которая соответствует конкретным требованиям дизайна. - person parrowdice; 05.11.2013
comment
Я также использую это с PIPE_TYPE_MESSAGE. - person xMRi; 05.11.2013
comment
@xMRi Нет гарантии, что канал удалит все данные. В приведенном выше сценарии ваш блокирующий вызов для чтения тела сообщения может действительно заблокировать. Кроме того, выполнение синхронного ввода-вывода на асинхронном дескрипторе может потерпеть неудачу незаметно. - person IInspectable; 05.11.2013
comment
1. Это правда, что у меня не все данные были сброшены... Но они поступят в ближайшие тики. Поскольку я читаю свой канал, и у меня есть отправитель-получатель, мне нечего делать для моего потока... Я знаю, что есть сообщение. - person xMRi; 05.11.2013
comment
2. Также Сценарий, на который вы указываете, тоже не соответствует. (Тоже я знаю об этой проблеме). Если есть канал и поток, который обрабатывает ввод-вывод между сервером канала и клиентом канала. Это отношение один к одному. Ручка используется для чтения внахлест. Когда я получаю хотя бы заголовок своего сообщения, я расшифровываю заголовок и читаю остальное. Между чтением заголовка и полной остальной части сообщения ввод/вывод выполняться не будет. - person xMRi; 05.11.2013