Не совсем понятно, о чем вы здесь спрашиваете, но я попробую.
Сводит ли ожидание APC на нет преимущества асинхронного ввода-вывода, полностью зависит от вашего проекта. Если вы написали что-то вроде:
WriteFileEx(..., &overlapped, CompleteWrite);
SleepEx(INFINITE, TRUE);
Тогда ясно, что вы ничего не добились, кроме чрезмерного усложнения вашей программы. Вы также можете использовать синхронный ввод-вывод.
Но вы также можете написать что-то вроде:
while (work_to_do)
{
DoSomeWork();
WriteFileEx(results);
SleepEx(0, TRUE);
}
Теперь вы избежали некоторого времени простоя. Если для завершения WriteFileEx требуется много времени, поток может тем временем продолжать работу.
Вы также можете создать поток, который обслуживает запросы. Что-то типа:
DWORD ThreadProc(...)
{
while (!done)
{
SleepEx(INFINITE, TRUE);
}
}
Этот поток просто сидит и ждет, пока кто-нибудь отправит ему команду, используя QueueUserAPC
. Если такой поток выполнил ввод-вывод, он может захотеть сделать это асинхронно, чтобы позволить ему обрабатывать другие команды, ожидая завершения ввода-вывода. (С другой стороны, чтобы избежать проблем с повторным входом, он может не этого делать.)
Я надеюсь, что это дает некоторое представление о том, как эти функции должны были использоваться. Но имейте в виду, что это очень старые технологии. Вы бы редко, если вообще когда-либо, использовали их в современной программе. Вместо этого используйте такие функции, как CreateThreadPoolIo
/StartThreadPoolIo
, чтобы Windows выполняла завершение ввода-вывода в выделенном для вас рабочем потоке. Или, что еще лучше, используйте библиотеку, ориентированную на задачи более высокого уровня, и избегайте этих низкоуровневых деталей.
EDIT – Выполнение ввода-вывода в потоке главного окна
Короткий ответ на эту конкретную проблему: не делайте этого. Запустите ввод-вывод в рабочем потоке и отправьте результаты обратно в основной поток, используя PostMessage
или SendMessage
. Если по какой-то причине вы не можете этого сделать, то вы должны использовать модифицированный цикл сообщений. Вместо GetMessage
используйте MsgWaitForMultipleObjects
, что позволит вам обрабатывать оконные сообщения, ожидая завершения ввода-вывода.
// error checking omitted
OVERLAPPED overlapped{};
ReadFile(file_handle, buffer, bytes_to_read, &bytes_read, &overlapped);
while (true)
{
DWORD wait_result = MsgWaitForMultipleObjects(
1,
&file_handle,
FALSE,
INFINITE,
QS_ALLINPUT);
if (wait_result = WAIT_OBJECT_0)
{
// I/O completed...
break;
}
}
person
Peter Ruderman
schedule
05.07.2018
GetOverLappedResult
, и вы можете поиграть с портами завершения ввода-вывода, чтобы создать шаблон реактора/проактора - person David Haim   schedule 05.07.2018MsgWaitForMultipleObjectsEx
сMWMO_ALERTABLE
. с этим вы можете обрабатывать сообщения Windows и apc - person RbMm   schedule 06.07.2018