سؤال

في Python ، يمكن استخدام الكلمة الرئيسية للعائد في كل من سياقات الدفع والسحب ، أعرف كيفية القيام بسياق السحب في C# ولكن كيف يمكنني تحقيق الدفع. أنشر الكود الذي أحاول تكراره في C# من Python:

def coroutine(func):
  def start(*args,**kwargs):
    cr = func(*args,**kwargs)
    cr.next()
    return cr
  return start

@coroutine
def grep(pattern):
  print "Looking for %s" % pattern
  try:
    while True:
      line = (yield)
      if pattern in line:
        print line,
  except GeneratorExit:
    print "Going away. Goodbye"
هل كانت مفيدة؟

المحلول

إذا كان ما تريده هو "مجموعة يمكن ملاحظتها" - أي مجموعة تدفع النتائج إليك بدلاً من السماح للمستهلك بسحبها - فربما تريد أن تنظر في ملحقات الإطار التفاعلي. هذا مقال حوله:

http://www.infoq.com/news/2009/07/Reactive-framework-linq-events

الآن ، كما تلاحظ ، يمكنك بناء كل من "Push" و "سحب" التكرار على النمط بسهولة إذا كان لديك Coroutines متاحًا. (أو ، كما يشير Thomas ، يمكنك بناءها مع استمرار أيضًا.) في الإصدار الحالي من C# ليس لدينا coroutines حقيقية (أو الاستمرارية). ومع ذلك ، نحن قلقون للغاية بشأن الألم الذي يشعر به المستخدمون البرمجة غير المتزامنة.

إن تنفيذ Coroutines المستندة إلى الألياف كميزة لغة من الدرجة الأولى هو إحدى التقنيات التي يمكن استخدامها لجعل البرمجة غير المتزامنة أسهل ، ولكن هذه مجرد فكرة واحدة محتملة للكثيرين الذين نبحث عنه في الوقت الحاضر. إذا كان لديك سيناريو رائع حقًا حيث تقوم Coroutines بعمل أفضل من أي شيء آخر - بما في ذلك الإطار التفاعلي - فأنا أحب أن أسمع المزيد عنها. البيانات الأكثر واقعية التي لدينا حول المشكلات الحقيقية التي يواجهها الناس في البرمجة غير المتزامنة ، كلما زاد احتمال توصلنا إلى حل جيد. شكرًا!

تحديث: لقد أعلنا مؤخرًا أننا نضيف تدفقات تحكم غير متزامنة تشبه Coroutine إلى الإصدار التالي من C# و VB. يمكنك تجربتها بنفسك مع إصدار معاينة تكنولوجيا المجتمع ، والتي يمكنك تنزيلها هنا.

نصائح أخرى

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

يمكن محاكاة المشاركين العامين مع المواضيع. كل موضوع له كومة خاصة به. في الإعداد المشترك للروتين ، سيقوم كل من المواضيع (المتصل الأولي ، والخيط الخاص بـ Co-Routine) بتبديل التحكم ، ولن يتم تشغيلهما فعليًا في وقت واحد. آلية "العائد" هي بعد ذلك تبادل بين الخيوط ، وبالتالي فهي مكلفة (المزامنة ، مستديرة من خلال kernel ومجدول OS ...). أيضًا ، هناك مساحة كبيرة لتسريبات الذاكرة (يجب إيقاف "الروتين المشترك" بشكل صريح ، وإلا فإن خيط الانتظار سوف يلتصق إلى الأبد). وبالتالي ، نادرا ما يتم ذلك.

C# يوفر ميزة روتين مشتركة تسمى التكرار. يقوم برنامج التحويل البرمجي C# تلقائيًا بتحويل رمز التكرار إلى فئة حالة معينة ، حيث أصبحت المتغيرات المحلية حقول فئة. العائد هو ، على مستوى VM ، سهل return. مثل هذا الشيء قابل للتنفيذ طالما يتم تنفيذ "العائد" من رمز التكرار نفسه ، وليس من طريقة يستدعي رمز التكرار. C# Comors Coverts بالفعل العديد من حالات الاستخدام وكان مصممو C# غير راغبين في الذهاب إلى أبعد من الطريق إلى الطريق الاستمرارية. يحرص بعض الأشخاص الساخرة على الإشارة إلى أن تنفيذ الاستمرارية الكاملة قد منعت C# من أن يكونوا فعالين مثل جافا عدوها القوس (الاستمرارية الفعالة ممكنة ، ولكن هذا يتطلب بعض العمل مع GC ومترجم JIT).

شكرًا Nicklarsen ، لقد ساعدتني في تذكر الأشياء الجديدة التي قدمتها MS ، واجهة iobservable.

حلقة الوصل http://msdn.microsoft.com/en-us/library/dd783449(vs.100).aspx

في الواقع ، لا يقدم .NET "افتراضات غير صحيحة" حول تقارب الخيط ، في الواقع يتفكيك تمامًا فكرة مؤشر ترابط مستوى .NET من مؤشر ترابط مستوى OS.

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

قد نجد مثالا هنا: http://msdn.microsoft.com/en-us/magazine/cc164086.aspx

BTW Mono 2.6 يحتوي على دعم كوروتين منخفض المستوى ويمكن استخدامه لتنفيذ جميع بدايات المستوى الأعلى بسهولة.

أحب أن أرى واجهة برمجة تطبيقات قائمة على الألياف لـ .NET.

لقد حاولت استخدام واجهة برمجة تطبيقات الألياف الأصلية في C# من خلال P/استدعاء لفترة من الوقت ، ولكن نظرًا لأن استثناء وقت التشغيل (بشكل غير صحيح) يجعل الافتراضات القائمة على الخيوط ، تنهار الأمور (بشكل سيء) عندما تحدث الاستثناءات.

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

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

حسنًا ، لقد حاولت تطوير مكتبة كاملة لإدارة Coroutines بخيط واحد فقط. كان الجزء الصعب هو استدعاء coroutines داخل Coroutines ... وإعادة المعلمات ، لكنني أخيرًا وصلت إلى نتيجة جيدة هنا. التحذير الوحيد هو أنه يجب إجراء عمليات إدخال الإدخال/الإخراج من خلال المهام ويجب استبدال "العودة" ALLL بـ "عودة العائد". مع خادم التطبيق استنادًا إلى هذه المكتبة ، تمكنت من مضاعفة الطلبات التي تم تقديمها تقريبًا باستخدام Async/Await القياسي بناءً على IIS. (ابحث عن node.cs و node.cs.musicstore على github لتجربته في المنزل)

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