Если я правильно понял вопрос, похоже, что клиент должен запустить waitloop, что-то вроде
while(!threadCancel)
{
DWORD waitResult = WaitForMultipleObjects(actionCount, waitHandles, FALSE, 500);
switch (waitResult)
{
case SERVER_COMMAND_1:
HandleServerCommand1();
break;
...etc...
default:
throw ...
}
}
Клиентские приемники событий запускают дескрипторы ожидания, эффективно позволяя серверу сообщать клиенту, что делать.