تنفيذ "واحد فقط من" و "ليس في متوازي" مع المكتبة الموازية للمهمة

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

  •  26-09-2019
  •  | 
  •  

سؤال

ما هو أفضل طريقة لتنفيذ المهام مع مفتاح يعمل على النحو التالي:-

الخيار 1) واحد فقط من هذا المفتاح معلق على الإطلاق. يمكن استخدامها ، على سبيل المثال ، من ASP.NET MVC لتصوير عرض واحد لصورة الصورة المصغرة بغض النظر عن عدد المرات التي يتم فيها ضرب عنوان URL للصورة. يتم تشغيل واحد فقط ، جميع الطلبات الأخرى تنتظر إكمال ذلك.

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

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

تبدو المهام المتداخلة ذات الاستمرارية متفائلة ولكن الحفاظ على قاموس لمهام قائمة الانتظار حاليًا ، سرعان ما تصبح فوضوية بين فصول TaskFactory و TaskScheduler. إن الوراثة من المهمة هي مشكلة أيضًا نظرًا لأن TaskFactory أو TaskScheduler عامة في المهمة.

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

هل قام أي شخص بتنفيذ أي شيء مشابه لهذا باستخدام TPL ، وإذا كان الأمر كذلك ، فما هو النهج الذي اتبعته في مهمتك ، والمهام ، وفئات TaskFactory؟

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

المحلول

ربما ، إحدى الطرق التي يمكنني التفكير بها

  1. قم بإنشاء فئة Wrapper - قل KeyProcessor لتصوير العناصر لمفتاح.
  2. ستكون طريقة keyprocessor.run () قادرة على أي دلالات في قائمة الانتظار التي تحتاجها. في الأساس ، سيبحث عن قائمة انتظار داخلية لأي عمل معلق ثم استمر في القيام بذلك بالتتابع.
  3. الحفاظ على قاموس كائنات المعالج.
  4. لأي مهمة جديدة ، تحقق من القاموس لنفس المفتاح. إذا لم يكن موجودًا ، فأضفه. قائمة انتظار المهمة عليها. إذا لم يتم تشغيله ، فقم بجدولةه باستخدام TPL باستخدام طريقة التشغيل كإجراء.
  5. استخدم Continuewith لجدولة مهمة المشرف - على سبيل المثال ، كلما تم الانتهاء من تنفيذ المهمة.

كل ما سبق سيكون صعبًا من نقطة Sync Point وليس لبعض المجموعات المثيرة للاهتمام الموجودة في System.Collections.Concurrent مساحة الاسم. هذا من شأنه أن يجعل المنطق أعلاه أكثر بساطة. فمثلا، ConcurrentDictionary.getoradd سيسمح للبحث و/أو إضافة كائن KeyProcessor بطريقة آمنة مؤشرات الترابط.

نصائح أخرى

هذه المشكلة تشبه تلك التي قمت بحلها ReactiveXaml, ، على الرغم من أني أيضا مذكرات الطلبات السابقة. ألقِ نظرة على الكود QueuedAsyncmrucacheإدخال المدونة) - يجمع هذا الرمز بين TPL مع الامتدادات التفاعلية لإنجاز هذا النوع من الأشياء ، ولكنه يجعل ضمانًا مهمًا بأن الطلب الثاني لنفس المفتاح سيحظر الطلب الأول بدلاً من إصدار واحد آخر.

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