CancelIoEx can cancel synchronous I/O, which is kind of nice

Raymond Chen

Raymond

The Cancel­Io­Ex function can be used to cancel synchronous I/O.

This is handy if you have a program that processes a file in large chunks and you want to give it a Cancel button. Without Cancel­Io­Ex, you would either have to accept that the program won’t respond to the Cancel button until the large I/O is complete, or you would have to change your program so it processed the file in small chunks, which is less efficient.

But with Cancel­Io­Ex, you can do your large chunk processing and still let the user cancel it immediately.

#define STRICT
#include <windows.h>
#include <stdio.h>

#define FILESIZE (200*1024*1024)

DWORD CALLBACK ThreadProc(void* h)
{
 void* buffer = VirtualAlloc(0, FILESIZE, MEM_COMMIT, PAGE_READWRITE);
 DWORD actual;
 auto result = ReadFile(h, buffer, FILESIZE, &actual, 0);
 auto lastError = GetLastError();
 printf("ReadFile -> %d, GetLastError = %d\n", result, lastError);
 return 0;
}

int __cdecl main(int, char**)
{
 auto h = CreateFile("D:\\setup.exe", GENERIC_READ, 0, 0,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
                    FILE_FLAG_NO_BUFFERING, 0);
  DWORD id;
  auto thread = CreateThread(0, 0, ThreadProc, h, 0, &id);
  Sleep(1000);
  CancelIoEx(h, nullptr);
  WaitForSingleObject(thread, INFINITE);
  return 0;
}

This program reads 200MB of data from a file that I hard-coded, which on my machine happens to be on a CD-ROM. One thread reads the beginning portion of the file into memory, and the other thread calls Cancel­Io­Ex to cancel the large I/O operation.

ReadFile -> 0, GetLastError = 995

Error 995 is

C:\> NET HELPMSG 995

The I/O operation has been aborted because of either
a thread exit or an application request.

which corresponds to ERROR_OPERATION_ABORTED, just like the documentation says.

Related reading: CancelIoEx can cancel I/O on console input, which is kind of nice.

Raymond Chen
Raymond Chen

Follow Raymond