هل هناك طريقة Waitone التي تستدعي إعادة التعيين أولاً؟

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

سؤال

أنا أستخدم autoresetevent حيث يمكن إجراء مكالمات متعددة في حدث (معالجة استثناء). هناك أوقات يتم فيها استدعاء مجموعة إضافية ، وبالتالي عندما يقوم الرمز بإجراء مكالمة ثانية في حدث Waitone ، فإنه يمر مباشرة لأنه تم فتح البوابة بالفعل.

الحل هو استدعاء إعادة تعيين مباشرة قبل وايتون. هل هناك حل أنظف أم أن هذه هي الطريقة الوحيدة للقيام بذلك؟ رمز المثال:

private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

بعد معالجة الاستثناء ، أحتاج إلى الاتصال بـ Dosomework مرة أخرى ، ولكن نظرًا لأن المجموعة قد تم استدعاؤها في استثناءات متعددة (أو استثناءات إعادة التثبيت) ، يتدفق Wiwtone فقط.

الحل الخاص بي هو الاتصال دائمًا بإعادة تعيينه قبل وايتون. هل هذا هو الحل المتدرب أو التصميم السيئ أم أن هناك نوعًا مختلفًا من الحدث الذي سيتعامل مع هذا السيناريو؟

تحرير: لقد نقلت للتو إعادة ضبط (الحل المقترح) بجوار الحدث.

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

المحلول

سيكون قلقي هو أنه إذا قمت باستدعاء Reset () قبل Waitone () ، فأنت في مشكلة إذا لم يتم استدعاء مجموعة () على الإطلاق. قد يحدث هذا إذا قمت باستدعاء Set () ، ثم اضغط على Reset () بعد ذلك مباشرة ، قبل أن تضغط على Waitone (). حتى إذا كنت تتصل بـ Set () مرتين ، فليس هناك ما يضمن أنك لن تتصل بـ RESET () بعد كليهما ، وتمنع الخيط بدون آلية للإصدار.

من الناحية المثالية ، ستحصل على محاولة .. كاتش .. حظرًا فصحلاً ، واتصل بالمجموعة () في الكتلة أخيرًا ، وليس لديك استثناء من معالجةك عبر الطرق. هل هذا مناسب لك؟

هانز صحيح أنه في هذا السيناريو ، فإن MultiThreading غير ضروري. تنطبق مخاوفي فقط إذا كنت متعددًا بالفعل مع مكالماتك إلى Waitone ().

يهمني أيضًا أنك تتصل بمجموعة أكثر من مرة ... هل هذا يعني أنه عندما يتم استدعاء المجموعة الأولى ، يجب أن يظل المورد مغلقًا حقًا؟ إذا كنت لا تزال قادرًا على الضغط على Set () مرة ثانية ، فإنني تقول إنك ما زلت تنفذ رمزًا يعمل مع الموارد المشتركة. في هذه الحالة ، لا تريد إلغاء الحظر.

لاحظ أيضًا ، من MSDN:

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

في أي حال ، يبدو أن الكود الخاص بك يجب أن يذهب إما إلى طريق رمي استثناء ، أو الجري حتى الانتهاء ، ولكن ليس كلاهما. أي يجب ألا تكون الاتصال () مرتين.

نصائح أخرى

هذه ليست مشكلة حقيقية ، فإن مكالمة Waitone () تعيد ضبط الحدث تلقائيًا. بعد كل شيء ، لقد استخدمت autoresetevent ، وليس manualseSetEvent. العبارة الرئيسية هنا هي إعادة تعيين تلقائي.

إن رؤيته تبخيرًا من خلال مكالمة Waitone () أمر طبيعي جدًا أيضًا. لقد حصلت على وحدة المعالجة المركزية الأساسية المتعددة اللطيفة ، وبدأ الخيط على الفور عندما اتصلت بـ Start () ولم تأخذ سوى عدد قليل من microseconds لإنجاز المهمة. ميلي ثانية ، أيا كان ، أسرع من غمضة عينك.

ربما أكثر من ذلك ، أنت لا تحتاج فقط إلى موضوع هنا. بدء واحدة ، ثم الانتظار حتى الانتهاء لا معنى له. فقط اتصل بـ dosomeotherstuff () مباشرة.

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