متى يمكنني استخدام AutoResetEvent وManualResetEvent بدلاً من Monitor.Wait()/Monitor.Pulse()؟

StackOverflow https://stackoverflow.com/questions/158133

سؤال

يبدو أن كلاهما يحققان نفس الغرض.متى سأختار أحدهما على الآخر؟

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

المحلول

استخدم الأحداث عندما كنت قد حصلت على الخيط الذي ينتظر على أحد أو كل عدد من الأحداث أن تفعل شيئا.

استخدم الشاشة إذا كنت ترغب في تقييد الوصول إلى بنية بيانات عن طريق الحد من كم المواضيع يمكن الوصول إليه.

شاشات عادة حماية مورد، في حين أن الأحداث اقول لكم شيئا ما يحدث، مثل تطبيق اغلاق.

وبالإضافة إلى ذلك، يمكن تسمية الأحداث (انظر طريقة OpenExisting)، وهذا يسمح لهم لاستخدامها لمزامنة عبر عمليات مختلفة.

نصائح أخرى

في رأيي، فمن الأفضل لاستخدام مراقب إذا كنت تستطيع، وتستخدم Monitor.Wait وMonitor.Pulse / PulseAll للانزعاج بين المواضيع (كما هي يدوي / AutoResetEvent) ولكن راقب هو أسرع، وعدم استخدام مواطن موارد النظام. كما يبدو هو رصد تنفيذها في وضع المستخدم ويتم إدارتها، في حين يدوي / AutoResetEvents يتطلب التحول إلى وضع وص نواة / استدعاء إلى دعوات Win32 والأم التي تستخدم مقبض الانتظار.

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

وأنا مجرد التقيؤ ما قرأته في هذا المقال ممتاز عن خيوط.

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

سوف تستخدم أ WaitHandle عندما تريد أن يرسل الخيط إشارة ثنائية أو يستقبلها بدون الحاجة إلى قسم حاسم. Monitor.Wait و Monitor.Pulse على الجانب الآخر يتطلب قسم حاسم.مثل معظم آليات المزامنة في BCL، هناك بعض التداخل في كيفية استخدام الآليتين اللتين ذكرتهما.لكن لا تظن للحظة أنهم يحققون نفس الغرض.

Monitor.Wait و Monitor.Pulse هي آلية مزامنة أكثر بدائية من التوعية بمخاطر الألغام أو ARE.في الواقع، يمكنك بالفعل إنشاء برنامج تعليم مخاطر الألغام أو استخدام لا شيء أكثر من Monitor فصل.المفهوم الأكثر أهمية لفهمه هو كيف Monitor.Wait و WaitHandle.WaitOne تختلف الأساليب. Wait و WaitOne كلاهما سيضع الخيط في WaitSleepJoin الحالة التي تعني أن الخيط يصبح خاملاً ولا يستجيب إلا لأي منهما Thread.Interrupt أو المعنية Pulse أو Set يتصل.ولكن، وهذا هو الفرق الرئيسي، Wait سيترك قسمًا مهمًا ويستعيده بطريقة ذرية. WaitOne ببساطة لا أستطيع أن أفعل هذا.إنه اختلاف أساسي جدًا في الطريقة التي تتصرف بها آليات المزامنة هذه والذي يحدد السيناريوهات التي يمكن استخدامها فيها.

في معظم الحالات، يمكنك اختيار التوعية بمخاطر الألغام أو ARE.تلبي هذه معظم المواقف التي يحتاج فيها خيط واحد إلى تلقي إشارة من خيط آخر.ومع ذلك، إذا كنت ترغب في إنشاء آلية الإشارات الخاصة بك، فسوف تحتاج إلى استخدامها Wait و Pulse.ولكن، مرة أخرى، يحتوي .NET BCL على معظم آليات الإشارة الشائعة التي تمت تغطيتها بالفعل.آليات الإشارة التالية موجودة بالفعل1.

  • ManualResetEvent (أو ManualResetEventSlim)
  • حدث إعادة الضبط التلقائي
  • سيمافور (أو سيمافور سليم)
  • EventWaitHandle
  • حدث العد التنازلي
  • حاجز

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

وهذا البرنامج التعليمي لديها وصفا تفصيليا لما عليك أن تعرف: http://www.albahari.com/threading/

وعلى وجه الخصوص، وهذا سوف تغطي فصول XXXResetEvent،
http://www.albahari.com/threading/part2.aspx

وهذا سوف تغطي انتظر / نبض: http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse

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