Основы программирования в Win32API. Марапулец Ю.В. - 67 стр.

UptoLike

Составители: 

полнение запроса на ввод/вывод при помощи вызова CanselIo(), соответст-
вующая операция ввода/вывода завершается с сообщением об ошибке
ERROR_OPERATION_ABORTED (это значение можно получить при помощи
вызова GetLastError()).
В случае, если было инициировано слишком большое количество за-
просов на асинхронный ввод/вывод, функция ReadFile() может завершиться
возвратом значения ERROR_INVALID_USER_BUFFER или ER-
ROR_NOTENOUGH_MEMORY.
В некоторых ситуациях для осуществления операций перекрывающегося
ввода/вывода удобнее использовать специально предназначенные для этого
функции ReadFileEx() и WriteFileEx(). Эти функции не могут использоваться
для обычного ввода/вывода. В качестве дополнительного аргумента каждый из
этих вызовов принимает указатель на функцию, которая будет вызвана в мо-
мент завершения операции ввода/вывода:
BOOL ReadFileEx
(HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
BOOL WriteFileEx
(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );…
Однако для того, чтобы произошло обращение к функции завершения,
поток, обратившийся к ReadFileEx() или WriteFileEx(), должен находиться
в «настороженном» состоянии. Чтобы перейти в настороженное состояние, не-
обходимо использовать вызовы WaitForSingleObject() или SleepEx(). Находясь
в настороженном состоянии, поток не выполняет никаких действий, а просто
ждет, когда в результате завершения операции ввода/вывода произойдет об-
ращение к функции завершения.
Все эти особенности перекрывающегося ввода/вывода несколько обеску-
раживают. Перекрывающийся ввод/вывод удобен во многих ситуациях, однако
он не настолько асинхронный, как этого хотелось бы программистам. Чтобы
реализовать действительно асинхронный ввод/вывод, следует создать отдель-
ный программный поток, в рамках которого можно использовать обычные
функции ввода/вывода. В качестве альтернативы при разработке некоторых
программ можно использовать порты завершения ввода/вывода (о них речь
пойдет чуть позже).
Если традиционная функция чтения данных в процессе осуществления
67
полнение запроса на ввод/вывод при помощи вызова CanselIo(), соответст-
вующая операция ввода/вывода завершается с сообщением об ошибке
ERROR_OPERATION_ABORTED (это значение можно получить при помощи
вызова GetLastError()).
     В случае, если было инициировано слишком большое количество за-
просов на асинхронный ввод/вывод, функция ReadFile() может завершиться
возвратом     значения     ERROR_INVALID_USER_BUFFER           или    ER-
ROR_NOTENOUGH_MEMORY.
     В некоторых ситуациях для осуществления операций перекрывающегося
ввода/вывода удобнее использовать специально предназначенные для этого
функции ReadFileEx() и WriteFileEx(). Эти функции не могут использоваться
для обычного ввода/вывода. В качестве дополнительного аргумента каждый из
этих вызовов принимает указатель на функцию, которая будет вызвана в мо-
мент завершения операции ввода/вывода:
    BOOL ReadFileEx
    (HANDLE hFile,
    LPVOID lpBuffer,
    DWORD nNumberOfBytesToRead,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );

    BOOL WriteFileEx
    (HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );…
     Однако для того, чтобы произошло обращение к функции завершения,
поток, обратившийся к ReadFileEx() или WriteFileEx(), должен находиться
в «настороженном» состоянии. Чтобы перейти в настороженное состояние, не-
обходимо использовать вызовы WaitForSingleObject() или SleepEx(). Находясь
в настороженном состоянии, поток не выполняет никаких действий, а просто
ждет, когда в результате завершения операции ввода/вывода произойдет об-
ращение к функции завершения.
     Все эти особенности перекрывающегося ввода/вывода несколько обеску-
раживают. Перекрывающийся ввод/вывод удобен во многих ситуациях, однако
он не настолько асинхронный, как этого хотелось бы программистам. Чтобы
реализовать действительно асинхронный ввод/вывод, следует создать отдель-
ный программный поток, в рамках которого можно использовать обычные
функции ввода/вывода. В качестве альтернативы при разработке некоторых
программ можно использовать порты завершения ввода/вывода (о них речь
пойдет чуть позже).
     Если традиционная функция чтения данных в процессе осуществления

                                   67