{"id":97105,"date":"2017-09-28T07:00:00","date_gmt":"2017-09-28T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97105"},"modified":"2019-03-13T01:17:36","modified_gmt":"2019-03-13T08:17:36","slug":"20170928-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170928-00\/?p=97105","title":{"rendered":"CancelIoEx can cancel synchronous I\/O, which is kind of nice"},"content":{"rendered":"<p>The <code>Cancel&shy;Io&shy;Ex<\/code> function can be used to cancel synchronous I\/O. <\/p>\n<p>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 <code>Cancel&shy;Io&shy;Ex<\/code>, you would either have to accept that the program won&#8217;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. <\/p>\n<p>But with <code>Cancel&shy;Io&shy;Ex<\/code>, you can do your large chunk processing and still let the user cancel it immediately. <\/p>\n<pre>\n#define STRICT\n#include &lt;windows.h&gt;\n#include &lt;stdio.h&gt;\n\n#define FILESIZE (200*1024*1024)\n\nDWORD CALLBACK ThreadProc(void* h)\n{\n void* buffer = VirtualAlloc(0, FILESIZE, MEM_COMMIT, PAGE_READWRITE);\n DWORD actual;\n auto result = ReadFile(h, buffer, FILESIZE, &amp;actual, 0);\n auto lastError = GetLastError();\n printf(\"ReadFile -&gt; %d, GetLastError = %d\\n\", result, lastError);\n return 0;\n}\n\nint __cdecl main(int, char**)\n{\n auto h = CreateFile(\"D:\\\\setup.exe\", GENERIC_READ, 0, 0,\n                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |\n                    FILE_FLAG_NO_BUFFERING, 0);\n  DWORD id;\n  auto thread = CreateThread(0, 0, ThreadProc, h, 0, &amp;id);\n  Sleep(1000);\n  CancelIoEx(h, nullptr);\n  WaitForSingleObject(thread, INFINITE);\n  return 0;\n}\n<\/pre>\n<p>This program reads 200<a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20090611-00\/?p=17933\">MB<\/a> 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 <code>Cancel&shy;Io&shy;Ex<\/code> to cancel the large I\/O operation. <\/p>\n<pre>\nReadFile -&gt; 0, GetLastError = 995\n<\/pre>\n<p>Error 995 is <\/p>\n<pre>\nC:\\&gt; <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20170919-00\/?p=97046\">NET HELPMSG<\/a> 995\n\nThe I\/O operation has been aborted because of either\na thread exit or an application request.\n<\/pre>\n<p>which corresponds to <code>ERROR_<\/code><code>OPERATION_<\/code><code>ABORTED<\/code>, just like the documentation says. <\/p>\n<p><b>Related reading<\/b>: <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150323-00\/?p=44413\">CancelIoEx can cancel I\/O on console input, which is kind of nice<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Get me out of there.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-97105","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Get me out of there.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=97105"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97105\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=97105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}