MSDN говорит, что:
«Функция ServiceMain должна создать глобальное событие, вызвать функцию RegisterWaitForSingleObject для этого события и завершить работу. Это прервет поток, в котором выполняется функция ServiceMain, но не прекратит работу службы …»
Поэтому вопрос таков: должен быть создан новый поток внутри функции ServiceMain для выполнения кода службы, или я могу просто установить службу в состояние RUNNING и использовать поток ServiceMain для запуска кода службы? Если поток ServiceMain используется для запуска служебного кода, SCM останется заблокированным, даже если для состояния службы установлено значение RUNNING?
Я не думаю, что способ реализации услуг, описанный в этом заявлении MSDN, является единственно возможным. Это противоречило бы примеру службы MSDN в http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476(v=vs.85).aspx . В этом примере служба ожидает события в том же потоке, который вызвал ServiceMain. Этот способ, вероятно, лучше подходит для простых сервисов, которые прекрасно работают с одним потоком.
Если вы решите использовать RegisterWaitForSingleObject, вам не нужно явно создавать потоки. Страница MSDN для RegisterWaitForSingleObject гласит: «Новые потоки ожидания создаются автоматически при необходимости». Вы должны открыть каналы ввода-вывода, которые будут обслуживать ваши службы, и привязать их дескрипторы к пулу потоков перед выходом из ServiceMain.
MSDN говорит: «Диспетчер управления службами (SCM) ожидает, пока служба не сообщит о состоянии SERVICE_RUNNING
, Рекомендуется, чтобы служба сообщала об этом состоянии как можно быстрее, так как другие компоненты системы, которые требуют взаимодействия с SCM, будут заблокированы в течение этого времени ».
Диспетчер управления создает новый поток для выполнения функции ServiceMain для службы. Функция ServiceMain должна выполнять следующий задачи.
5. Выполните служебные задачи или, если нет ожидающих выполнения задач, верните управление вызывающей стороне. Любое изменение в государственной службе ордеров
вызовSetServiceStatus
сообщить новую информацию о статусе.
От этот Из примера следует, что вы можете выполнять более сложные задачи инициализации внутри функции ServiceMain, такие как создание дополнительных потоков.
Руководство по созданию Многопоточные сервисы.