Я пытаюсь установить таймаут для операции чтения моего именованного канала.
Для чтения из именованного канала я использую ReadFile
функция.
Я прочитал, что тайм-аут может быть установлен для этой функции с SetCommTimeouts
функция, но когда я пытаюсь использовать его, я получаю системную ошибку 1: «Неправильная функция».
Вот мой код (это на стороне клиента):
m_pipe = CreateFileA(pipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
if (m_pipe != INVALID_HANDLE_VALUE)
{
DWORD mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
ok = SetNamedPipeHandleState(m_pipe, &mode, NULL, NULL);
COMMTIMEOUTS cto;
cto.ReadTotalTimeoutConstant = 1000;
BOOL time = SetCommTimeouts(m_pipe, &cto);
}
Я делаю что-то не так или SetCommTimeouts
метод не должен использоваться с трубами? Есть ли другой способ получить тайм-аут чтения?
Вы не можете использовать SetCommTimeouts с именованными каналами. Если вы хотите тайм-ауты, вам придется использовать Async I / O и реализовать тайм-аут самостоятельно, используя CancelIo
или же CancelIoEx
Если цель таймаута — не застрять forever
Вы можете рассмотреть звонок PeekNamedPipe (…) в синхронизированном цикле. Таким образом, вы можете проверить, есть ли время от времени что-нибудь прочитать.
альтернативно PeekNamedPipe
может использоваться, чтобы решить, действительно ли чтение на канале получит что-нибудь до чтение выполняется. Таким образом, «ожидающего» чтения можно избежать.
ReadFile блокирует, пока не будет прочитано запрошенное количество байтов или произойдет ошибка / прерывание. Перекрытые работы одинаковы, то есть завершаются на одинаковых условиях. Попытался реализовать таймауты с помощью CancelIoEx и выяснил, что он теряет данные. До сих пор не вижу способа реализации тайм-аутов и чтения только части запрошенного количества байтов или чтения кэшированных данных.