Вы можете отменить синхронный ввод/вывод (I/O) данных из любого потока в процессе, который запустил операцию ввода/вывода. Вы должны определить дескриптор потока, который, осуществлял операцию текущего ввода - вывода (I/O).
Пример ниже показывает две процедуры:
Обратите внимание! на то, что в этом примере поток UI мог также проверить существование рабочего потока. |
Дополнительные инструкции по проверкам, которые, не включаются здесь, требуются в процедуре SynchronousIoWorker для гарантии того, что, если отмена запрашивалась в ходе коротких периодов между вызовами файлового ввода-вывода (I/O), то оставшаяся часть операции должна быть отмененной.
Обратите внимание! на то, что в этом примере отмена, возможно, произошла где-нибудь в последовательности операций, это может быть необходимо для вызывающей программы, чтобы гарантировать, что состояние является последовательным, или по крайней мере понятым, перед тем, как продолжить работу. |
DWORD gCompletionStatus; // Статус завершения для последней операции DWORD dwOperationInProgress; // TRUE, если операция выполняется VOID SynchronousIoWorker( VOID * pv ) { LPCSTR lpFileName = (LPCSTR) *pv; HANDLE hEvent = lpCreateParams->hEvent; HANDLE hFile; dwOperationInProgress = TRUE; gCompletionStatus = ERROR_SUCCESS; hFile = CreateFileA(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { // TODO: CreateFile завершилась успешно. // Вставьте свой код, чтобы сделать больше синхронных вызовов с hFile. if (result == FALSE) { // Операция завершалась ошибкой или была отменена. Если она была отменена, // GetLastError() возвратит ERROR_OPERATION_ABORTED. gCompletionStatus = GetLastError(); } CloseHandle(hFile); } else { // CreateFile завершалась ошибкой или была отменена. Если она была отменена, // GetLastError() возвратит ERROR_OPERATION_ABORTED. gCompletionStatus = GetLastError(); } dwOperationInProgress = FALSE; } // Конец SynchronousIoWorker( ) //-------------------------------------------------------- LRESULT CALLBACK MainUIThreadMessageHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HANDLE syncThread; // Вставьте свои инициализации здесь. switch (uMsg) { // Пользователь запросил операцию на файле. Вставьте свой код, // чтобы извлечь имя файла из параметров. case WM_MYSYNCOPS: syncThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SynchronousIoWorker, &lpFileName, 0, NULL); if (syncThread == INVALID_HANDLE_VALUE) { // Вставьте свой код, чтобы обработать сбой. } break; // Пользователь щелкнул по кнопке отмены. case WM_MYCANCEL: if (syncThread != INVALID_HANDLE_VALUE) { CancelSynchronousIo(syncThread); } break; // Пользователь затребовал другую операцию. case WM_PROCESSDATA: if (!dwOperationInProgress) { if (gCompletionStatus == ERROR_OPERATION_ABORTED) { // Вставьте свой код очистки здесь. } else if (...) { // Вставьте код обработки других случаев. } } break; } // Конец switch (uMsg) return TRUE; } // Конец MainUIThreadMessageHandler( )
|