Я пытаюсь опосредовать небольшой сервис Windows, заставляя его ждать сигнала от другого процесса во время запуска. Я точно знаю, что такой подход может (или даже будет) иногда приводить к таймауту запуска службы. Это не так.
Проблема связана с именованным System.Thread.Sempaphore, который я использую для посреднических целей. Семафор создается и приобретается где-то еще, используя следующую конструкцию. В GC нет никаких изменений, поскольку я явно прерываю выполнение прямо под данной строкой для целей тестирования.
Boolean newOne;
System.Threading.Semaphore rootSemaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out newOne);
Очевидно, код выше работает хорошо. Следующий код хорошо работает при выполнении в режиме отладки или в консольном приложении:
Boolean createdNew;
System.Threading.Semaphore semaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
if (createdNew)
throw new Exception("That's not what we wanted");
Точно такой же код дает сбой при выполнении как часть службы Windows:
static class Program
{
static void Main(string[] args)
{
Boolean createdNew;
System.Threading.Semaphore semaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
if (createdNew)
throw new Exception("That's not what we wanted");
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new Dummy() };
ServiceBase.Run(ServicesToRun);
}
}
Итак, ищите помощь по этому вопросу.
PS: Я пытался вместо этого использовать Mutex, однако с ним была другая проблема — ожидающее приложение не догоняет, когда владелец вызывает Mutex.ReleaseMutex();
ОБНОВЛЕНИЕ :
Согласно ответу Анурага Ранджхана, я отредактировал процедуру создания семафора следующим образом, и теперь все работает нормально:
Boolean newOne = false;
System.Security.Principal.SecurityIdentifier sid =
new System.Security.Principal.SecurityIdentifier(
System.Security.Principal.WellKnownSidType.WorldSid,
null);
System.Security.AccessControl.SemaphoreSecurity sec =
new System.Security.AccessControl.SemaphoreSecurity();
sec.AddAccessRule(new System.Security.AccessControl.SemaphoreAccessRule(
sid,
System.Security.AccessControl.SemaphoreRights.FullControl,
System.Security.AccessControl.AccessControlType.Allow));
System.Threading.Semaphore rootSemaphore =
new Semaphore(1, 1, "Global\\DummyServiceSemaphore", out newOne, sec);