Если вы размещаете свое приложение-ответ на IIS, просто добавьте файл web.config, содержащий:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
</configuration>
. Это скажет серверу IIS, чтобы вернуть основную страницу клиенту вместо ошибки 404 и нет необходимости использовать историю хэша.
Прежде всего, IOCP здесь абсолютно не связаны. Вы пытаетесь проверить, являются ли операции ввода-вывода (читаются в вашем случае) на дескрипторе асинхронного дескриптора файла немедленным или блокированным. как здесь связан iocp ? Привязать iocp к файлу - это единственный способ получить уведомление, когда ввод-вывод завершен. но это абсолютно не влияет на сам блок ввода / вывода или немедленный возврат. мы можем использовать любой способ уведомления здесь. (APC, IOCP или событие). для вашего теста наиболее просто использовать событие.
тогда давайте посмотрим, как - как вы тестируете - читается блок или возвращается в ваш код? Вы не проверяете это вообще. проверьте эту потребность после возврата ReadFile
- операция завершена или нет. операция ввода / вывода (ReadFile) завершается асинхронно - если вызов API уже возвращает вам управление, но OVERLAPPED
(IO_STATUS_BLOCK
) еще не обновлен системой, что означает, что ввод / вывод еще не завершен. OVERLAPPED
обновлены, мы можем проверить прямой (Internal
член структуры OVERLAPPED
является не STATUS_PENDING
) или по вызову GetOverlappedResult
с bWait [ 1127] установлен в FALSE
Если этот параметр равен
blockquote>FALSE
и операция еще не завершена, функция возвращаетFALSE
, а функцияGetLastError
возвращаетERROR_IO_INCOMPLETE
., поэтому мы можем сказать, что
ReadFile
завершено асинхронно, если следующие 4 кодировки верны:
ReadFile
returnFALSE
GetLastError()
returnERROR_IO_PENDING
GetOverlappedResult(.., FALSE)
returnFALSE
GetLastError()
returnERROR_IO_INCOMPLETE
Вы не проверяете это в собственном коде. вместо этого вы ждете, пока операция io полностью не завершится через
GetOverlappedResult(.., true)
, и занимает некоторое время. и какой смысл это делать?реальный код для теста:
void tt(PCWSTR FileName) { HANDLE hFile = CreateFile(FileName, FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hFile != INVALID_HANDLE_VALUE) { OVERLAPPED ov {}; if (ov.hEvent = CreateEvent(0, 0, 0, 0)) { char buf[1024]; if (ReadFile(hFile, buf, sizeof(buf), 0, &ov)) { DbgPrint("sync(#1)\n"); } else { switch (GetLastError()) { case ERROR_IO_PENDING: ULONG n; if (GetOverlappedResult(hFile, &ov, &n, FALSE)) { DbgPrint("sync(#2)\n"); } else { switch (GetLastError()) { case ERROR_IO_INCOMPLETE: DbgPrint("async\n"); if (!GetOverlappedResult(hFile, &ov, &n, TRUE)) { __debugbreak(); } break; default: __debugbreak(); } } break; default: __debugbreak(); } } CloseHandle(ov.hEvent); } CloseHandle(hFile); } }
обратите внимание, что результат (синхронный или нет) завершенного чтения зависит от того, являются ли данные файла в кеше. если вы вызываете его для файла, который не был прочитан ранее (то есть данные не в кеше), возможно, API выдает «async», но если вы снова вызовете эту функцию для того же файла - вы в следующий раз быстрее всех (почти на 100%) просмотр "sync (# 2)"