8.13. التحكم في الحلقة

لا تتعامل معظم برامج asyncio النصية مع حلقة الأحداث مباشرةً أبدًا -- إذ تكفي asyncio.run(). تغطي هذه الصفحة سطح Loop للحالات التي لا تكفي فيها: تثبيت معالج استثناءات، أو تشغيل الحلقة بدورة حياة مختلفة عن run، أو الاحتفاظ بكائن الحلقة للقياس.

8.13.1. الحصول على الحلقة

  • asyncio.get_event_loop() -- يعيد كائن Loop. وآمن للاستدعاء من داخل كوروتين أو خارجها.

  • asyncio.new_event_loop() -- على MicroPython، يعيد ضبط حالة الحلقة الموجودة بدلًا من إنشاء حلقة جديدة. وتجدر إعادة الملاحظة: هناك حلقة أحداث واحدة بالضبط لكل برنامج.

لا توجد واجهة برمجية لـ تشغيل الحلقة بخلاف الطرق على Loop و asyncio.run().

8.13.2. تشغيل الحلقة مباشرةً

asyncio.run() هي نقطة الدخول الصحيحة لكل تطبيق تقريبًا. وتوجد طريقتان من Loop للحالات التي لا تكون فيها كذلك.

  • run_until_complete() -- بإعطاء كائن قابل للانتظار، تشغّل الحلقة حتى ينتهي ذلك الكائن، ثم تعيد نتيجته. وهي تعادل استدعاءً واحدًا لـ asyncio.run()، مع حذف هدم الحلقة.

  • run_forever() -- تشغّل الحلقة حتى يُستدعى stop() من داخل مهمة. لا يوجد كائن قابل للانتظار على المستوى الأعلى؛ ويُتوقع من التطبيق أن يجدول ما يحتاجه عبر asyncio.create_task() قبل استدعاء run_forever.

الطريقتان المرافقتان هما stop() (طلب إيقاف الحلقة بعد انتهاء المهمة الحالية) و close() (تحرير موارد الحلقة).

8.13.3. إنشاء المهام من جهة الحلقة

  • create_task() -- العملية نفسها مثل asyncio.create_task(). وتوجد الدالة الحرة كي لا تحتاج شيفرة التطبيق إلى مرجع للحلقة في الحالة الشائعة؛ وتوجد الطريقة للقياس الذي لديه مرجع بالفعل.

8.13.4. معالجات الاستثناءات

تستدعي الحلقة معالجًا عندما تطلق مهمة استثناءً لم يلتقطه أي شيء في سلسلة استدعاءات الكوروتين -- وحالة نموذجية هي مهمة أنشأها التطبيق بـ asyncio.create_task() ولم ينتظرها قط. يطبع المعالج الافتراضي تتبعًا عكسيًا عبر sys.stderr؛ وقد أظهرت صفحة الاستثناءات كيفية استبداله بشيء مخصّص.

  • set_exception_handler() -- تثبيت معالج مخصّص. والمعالج هو كائن قابل للاستدعاء handler(loop, context) حيث يكون context قاموسًا يحتوي على الأقل على 'message' وعادةً على 'exception' و 'future'.

  • get_exception_handler() -- يعيد المعالج المثبّت حاليًا، أو None إذا كان الافتراضي قيد الاستخدام.

  • default_exception_handler() -- المعالج المدمج. مفيد داخل معالج مخصّص يريد أن يشغّل أيضًا السلوك الافتراضي (التسجيل في ذاكرة فلاش و طباعة تتبع عكسي، على سبيل المثال).

  • call_exception_handler() -- يشغّل المعالج المثبّت حاليًا مع قاموس سياق مبني يدويًا. تستخدمه الحلقة نفسها في الغالب؛ ونادرًا ما يحتاجه التطبيق.