سؤال

ملخص سريع مع ما أعرفه الآن

لقد حصلت على EventWaitHandle التي قمت بإنشائها ثم أغلقت. عندما أحاول إعادة إنشائها مع هذا ctor, ، يتم رفض "الوصول إلى المسار ... تم رفضه". هذا الاستثناء أمر نادر الحدوث ، في معظم الأحيان يعيد خلق EventWaitHandle بخير. مع الإجابة المنشورة أدناه (من قبلي) ، يمكنني الاتصال بنجاح EventWaitHandle.OpenExisting واستمر في حالة إلقاء استثناء ، ومع ذلك ، فإن CTOR EventWaitHandle كان ينبغي أن تفعل هذا من أجلي ، أليس كذلك؟ أليس هذا ما المعلمة خارج, createdNew هو ل؟


السؤال الأول

لقد حصلت على الهندسة المعمارية التالية وخدمة Windows وخدمة ويب على نفس الخادم. تخبر خدمة الويب خدمة Windows أنه يتعين عليها القيام بالعمل عن طريق فتح ومقبض الانتظار الذي تنتظره خدمة Windows.

عادةً ما يكون كل شيء خالٍ من العيوب وأتمكن من بدء / إيقاف خدمة Windows دون ظهور أي مشكلة. ومع ذلك ، في بعض الأحيان عندما أوقف خدمة الويب ثم ابدأها مرة أخرى ، لن يتمكن تمامًا من إنشاء مقبض الانتظار ، وكسر الهندسة المعمارية بأكملها.

أحتاج على وجه التحديد إلى معرفة ما هو كسر مقبض انتظار الحدث وإيقافه. عندما يكون مقبض الانتظار "Breaks" ، يجب أن أعيد تشغيل 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: Global\OurCompany.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 'Global\OurCompany.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: كانت خدمة الويب قادرة فعليًا على فتح مجموعة مكالمات Hawn Handle () دون أي استثناء إلخ.

  • 12: 02: 00000: حاولت إعادة تشغيل خدمة Windows ، نفس الاستثناء

  • 12: 36: 57،328: بعد الانتظار التعسفي 36 دقيقة ، تمكنت من بدء خدمة Windows دون إعادة تشغيل النظام الكامل.


رمز خدمة 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,
 @"Global\OurCompany.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(
    @"Global\OurCompany.OurProduct.MyClass.EventWaitHandle");

استغلال:

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

منذ EventWaitHandle هو متغير عضو في خدمة الويب ، ليس لدي أي رمز يغلقه على وجه التحديد. في الواقع ، الكود الوحيد الذي يتفاعل مع EventWaitHandle يتم نشر خدمة الويب أعلاه.


إذا نظرنا إلى الوراء ، ربما كان ينبغي علي وضع Close() هذا في catch كتلة ، في أ finally كتلة بدلا من ذلك. ربما كان ينبغي علي فعل الشيء نفسه بالنسبة لخدمة الويب ، لكنني لم أكن أعتقد أنه كان مطلوبًا.

على أي حال ، هل يمكن لأي شخص أن يرى ما إذا كنت أفعل أي شيء خاطئ على وجه التحديد؟ هل من المهم للغاية وضع العبارات الوثيقة داخل كتلة أخيرًا؟ هل أحتاج إلى التحكم يدويًا في Close() التابع existing_ewh على خدمة الويب؟

أيضًا ، أعلم أن هذه مشكلة معقدة قليلاً ، لذا اسمحوا لي أن أعرف ما إذا كنت بحاجة إلى أي معلومات إضافية ، سأراقبها عن كثب وإضافة أي معلومات أو تفسيرات مطلوبة.

مادة مرجعية

هل كانت مفيدة؟

المحلول

في الكود الذي ينشئ مقبض الانتظار على خدمة Windows ، إذا فشل (كما هو الحال في Access Dained) ، يمكنك محاولة "فتح مقبض انتظار موجود" عبر

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

رغم ذلك ، لست متأكدًا تمامًا مما إذا كان السلوك سيبقى كما هو في تلك المرحلة.

ملاحظة: أقدر ردود الفعل. إنها إجابة محتملة ، لذا فأنا أجيب على سؤالي ، مرة أخرى ، الكثير من التعليقات مرحب بها تمامًا!

الملاحظة 2: بشكل مثير للدهشة ، تطبيق EventWaitHandleRights.FullControl بدلا من الأعلام أعلاه (Synchronize + Modify) لا يعمل بشكل جيد. يجب عليك استخدام العينة أعلاه.

نصائح أخرى

يقول MSDN:

UnauredizedAccessException - يوجد الحدث المسماة ولديه أمن التحكم في الوصول ، لكن المستخدم لا يحتوي على EventWaithandlerights.FullControl.

و

يتمتع المتصل بالتحكم الكامل في كائن EventWaithandle الذي تم إنشاؤه حديثًا حتى لو رفض EventSecurity أو فشل في منح بعض حقوق الوصول إلى المستخدم الحالي.

لا تملك خدمتك حقوقًا في الحصول على الحدث الحالي عبر مُنشئ EventWaithandle. (EventWaithAndlerights.fullControl لم يتم تحديده. ويوجد الحدث المسماة الخاص بك أثناء فتحه على مقابض.) يمكنك فتح الحدث الحالي باستخدام EventWaithandle.OpenExisting.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top