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() -- يشغّل المعالج المثبّت حاليًا مع قاموس سياق مبني يدويًا. تستخدمه الحلقة نفسها في الغالب؛ ونادرًا ما يحتاجه التطبيق.