Мой EventWaitHandle говорит "доступ к пути запрещен", но его не

краткое резюме с тем, что я теперь знаю

у меня есть EventWaitHandle что я создал, а затем закрывается. Когда я пытаюсь воссоздать его с помощью этот ctor, "доступ к пути ... запрещен" исключение. Это исключение редко, в большинстве случаев оно просто воссоздает EventWaitHandle просто отлично. С ответом, опубликованным ниже (мной), я могу успешно позвонить EventWaitHandle.OpenExisting и продолжить в случае, если исключение было вызвано, однако, ctor для EventWaitHandle должны были сделать это для меня, верно? Разве это не то, что out параметр, createdNew это?


первый вопрос

у меня есть следующая архитектура, служба windows и веб-служба на одном сервере. Веб-служба сообщает службе windows, что она должна выполнить работу, открыв и установив дескриптор ожидания, который ожидает служба windows.

нормально все безупречно и Я могу запустить / остановить службу windows без каких-либо проблем. Однако несколько раз, когда я останавливаю веб-службу, а затем запускаю ее снова, она будет полностью неспособна создать дескриптор ожидания, нарушая всю архитектуру.

мне конкретно нужно выяснить, что нарушает дескриптор ожидания события и остановить его. Когда дескриптор ожидания "ломается", я должен перезагрузить windows, Прежде чем он снова будет функционировать должным образом, и это, очевидно, не идеальный.

обновление: исключение брошено & журнал проблемы

я перезагрузил службу windows, пока веб-служба выполняла работу в надежде вызвать проблему, и это произошло! Некоторые имена классов подверглись цензуре из-за корпоративной анонимности

12:00:41,250 [7] - Stopping execution due to a ThreadAbortException
System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
   at OurCompany.OurProduct.MyClass.MyClassCore.MonitorRequests()

12:00:41,328 [7] - Closing Event Wait Handle
12:00:41,328 [7] - Finally block reached


12:00:42,781 [6] - Application Start
12:00:43,031 [6] - Creating EventWaitHandle: GlobalOurCompany.OurProduct.MyClass.EventWaitHandle
12:00:43,031 [6] - Creating EventWaitHandle with the security entity name of : Everyone

12:00:43,078 [6] - Unhandled Exception 
System.UnauthorizedAccessException: Access to the path 'GlobalOurCompany.OurProduct.MyClass.EventWaitHandle' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.Threading.EventWaitHandle..ctor(Boolean initialState, EventResetMode mode, String name, Boolean& createdNew, EventWaitHandleSecurity eventSecurity)
   at OurCompany.OurProduct.MyClassLibrary.EventWaitHandleFactory.GetNewWaitHandle(String handleName, String securityEntityName, Boolean& created)
   at OurCompany.OurProduct.MyClassLibrary.EventWaitHandleFactory.GetNewEventWaitHandle()
   at OurCompany.OurProduct.MyClass.MyClassCore..ctor()

грубой сроки:

  • 11: 53: 09,937: последний поток в веб-службе, чтобы открыть существующий дескриптор ожидания, завершил свою работу (как в завершенном соединении с клиентом)

  • 12:00:30,234: веб-служба получает новые соединения, не используя дескриптор ожидания. Идентификатор потока для этого соединения совпадает с идентификатором потока для последнего соединения в 11: 53

  • 12: 00: 41,250: служба windows останавливается

  • 12: 00: 42,781: служба windows запускается

  • 12: 00: 43,078: служба windows завершена сбой

  • 12: 00: 50,234: веб-служба фактически смогла открыть набор вызовов дескриптора ожидания () на нем без каких-либо исключений и т. д.

  • 12: 02: 00,000: я попытался перезагрузить службу windows, то же исключение

  • 12: 36: 57,328: после произвольного ожидания 36 минут я смог запустить службу windows без полной перезагрузки системы.


окна Сервисный Код

инициализации:

// I ran into security issues so I open the global EWH
//    and grant access to Everyone
var ewhSecurity = new EventWaitHandleSecurity();

ewhSecurity.AddAccessRule(
 new EventWaitHandleAccessRule(
  "Everyone",
  EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
  AccessControlType.Allow));

this.ewh = new EventWaitHandle(
 false,
 EventResetMode.AutoReset,
 @"GlobalOurCompany.OurProduct.MyClass.EventWaitHandle",
 out created,
 ewhSecurity);

// the variable "created" is logged

использование:

// wait until the web service tells us to loop again
this.ewh.WaitOne();

удаления / закрытия:

try
{
    while (true)
    {
        // entire service logic here
    }
}
catch (Exception e)
{
    // should this be in a finally, instead?
    if (this.ewh != null)
    {
        this.ewh.Close();
    }
}

Код Веб-Службы

инициализации:

// NOTE: the wait handle is a member variable on the web service
this.existing_ewh = EventWaitHandle.OpenExisting(
    @"GlobalOurCompany.OurProduct.MyClass.EventWaitHandle");

использование:

// wake up the windows service
this.existing_ewh.Set();

С EventWaitHandle является переменной-членом в веб-службе, у меня нет кода, который специально закрывает его. На самом деле, единственный код, который взаимодействует с EventWaitHandle на веб-сервисе размещена выше.


оглядываясь назад, я, вероятно, должен был поставить Close() это в catch блок, в блок. Вероятно, я должен был сделать то же самое для веб-службы, но я не думал, что это необходимо.

в любом случае, может ли кто-нибудь увидеть, делаю ли я что-то конкретно неправильно? Крайне ли важно поместить утверждения close в блок finally? Нужно ли вручную управлять Close() из existing_ewh на веб-сервис?

кроме того, я знаю, что это немного сложный вопрос, так дайте мне знать, если вам нужна дополнительная информация, я буду внимательно следить за ним и добавлять любую необходимую информацию или объяснения.

справочные материалы

2 ответов


в коде, который создает дескриптор ожидания в службе windows, если это не удается (как в access denied), вы можете попытаться "открыть существующий дескриптор ожидания" через

EventWaitHandle.OpenExisting(
    @"Global\OurCompany.OurProduct.MyClass.EventWaitHandle",
    EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify);

хотя, я не совсем уверен, останется ли поведение таким же в этот момент.

Примечание: я был бы признателен за обратную связь. Его потенциальный ответ, поэтому я отвечаю на свой собственный вопрос, опять же, множество комментариев приветствуются!

примечание 2: удивительно, применяя EventWaitHandleRights.FullControl вместо выше флаги (Synchronize + Modify) не работает. Вы должны использовать образец выше.


MSDN говорит:

UnauthorizedAccessException-именованное событие существует и имеет безопасность управления доступом, но пользователь не имеет EventWaitHandleRights.Полный контроль.

и

вызывающий объект имеет полный контроль над вновь созданным объектом EventWaitHandle, даже если eventSecurity запрещает или не предоставляет некоторые права доступа текущему пользователю.

ваш сервис не имеет прав на получение существующего события через EventWaitHandle конструктор. (EventWaitHandleRights.FullControl не указан. И Ваше именованное событие существует, пока оно открыло дескрипторы на нем.) Вы можете открыть существующее событие с помощью EventWaitHandle.Перегруженный метод openexisting.