تطبيق طلب المهمة باستخدام المكتبات الموازية للمهمة .NET 4.0

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

سؤال

لديّ برنامج يحتوي على الكثير من المستشعرات التي تنتج بيانات بمعدل مرتفع إلى حد ما ، والمستهلكين الذين يحتاجون إلى استهلاكها. المستهلكون يستهلكون بمعدلات مختلفة للغاية.

نظرًا لأنني أستخدم iobserver/iobservable ، فإن الحل التافلي كان ببساطة إنشاء مهمة لكل حدث ولف مكالمة onnext () والبيانات في LAMDA. لقد عمل هذا بشكل جيد للغاية ، لقد فوجئت بمدى قلة النفقات العامة على المكالمات الخام.

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

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

ثلاث مشاكل فورية مع هذا النهج. إنه أبطأ بكثير من حل المهمة/onnext (). لا يوجد حظر dequeue (أو هل هناك؟) للتوازي ، لذا فإن التنفيذ صعب بعض الشيء. والثالث هو أن هذا يبدو مشكلة شائعة لدرجة أنني لا أستطيع أن أتخيل أنه لا توجد طريقة لإنفاذ النظام الذي فاتني ، ربما شيء مثل مصانع المهام المتعددة التي تشترك في تجمع أساسي ، كل مصنع مع بعض الإعدادات التي تجعلها تنفذ بدقة ترتيب.

أي شخص يعرف الطريقة الصحيحة لتحقيق ما أحاول فعله؟

تحرير: أي حل يتضمن مؤشر ترابط لكل مستهلك أو منتج لا يعمل. المنتجون/المستهلكون يشكلون سلاسل طويلة ، وهناك المئات من كل منهم.

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

المحلول

ال مكتبة TPL DataFlow قد تكون مناسبة لتطبيقك. يمتد TPL مع نموذج تدفق البيانات الذي يتيح لك تكوين رسم بياني معالجة وتشغيله في بيئة تنفيذ عالية الأداء.

تتوفر TPL DataFlow كمكتبة أعلى .NET 4 ويجب أن تشحن كجزء من .NET 4.5.

نصائح أخرى

لا يوجد تعليق على أفضل تجريد لفرض الطلب الجزئي ، ولكن إذا كنت تستخدم أ BlockingCollection<T> غلاف حول أ ConcurrentQueue<T>, ، سيعطيك ذلك حظرًا Take تشغيل عناصر dequeue. على سبيل المثال:

// the default is ConcurrentQueue, so you don't have to specify, but if you
// wanted different behavior you could use e.g. ConcurrentStack

var coll = new BlockingCollection<int>(new ConcurrentQueue<int>());

coll.Add(5); // blocks if the collection is at max capacity

int five = coll.Take(); // blocks if the collection is empty
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top