Вы можете отменить асинхронный ввод/вывод (I/O) данных из любого потока в процессе, который запустил операцию ввода/вывода. Вы должны определить дескриптор потока, который, осуществлял ввод - вывод (I/O) и, необязательно, асинхронной структуры, которая использовалась, чтобы выполнить ввод - вывод. Вы можете определить, имела ли место отмена, проверяя статус, возвращенный в асинхронной структуре или в обратном вызове завершения. Статус ERROR_OPERATION_ABORTED указывает, что операция отменялась.
Пример ниже показывает процедуру, которая получает блокировку по времени и делает попытку операции чтения, отменяя её функцией CancelIoEx, если блокировка по времени заканчивает действие по истечению срока.
BOOL DoCancelableRead(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped, DWORD dwTimeout, LPBOOL bCancelCalled) { BOOL result; DWORD waitResult; *bCancelCalled = FALSE; result = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped ); if (!result) { if (GetLastError() != ERROR_IO_PENDING) { return result; } } else { return result; } // Ввод - вывод (I/O) находится в ожидании, так что ожидаем и смотрим прерывается ли вызов. // Обратите внимание: Асинхронное событие должно быть установлено перед // вызовом этой процедуры. waitResult = WaitForSingleObject(lpOverlapped->hEvent, dwTimeout ); if (waitResult == WAIT_TIMEOUT) { result = CancelIoEx(hFile, lpOverlapped ); *bCancelCalled = TRUE; // Ожидаем завершения ввода-вывода. Обратите внимание: Фактически вызов может быть, но // может и не быть отменен, что зависит от интервала ожидания // вызова. waitResult = WaitForSingleObject( lpOverlapped->hEvent, 0 ); } return result; } |