تطبيقات تتعطّل عند الاستئناف من السكون ── كيف تعمل أحداث الطاقة في Windows وكيف تبني تطبيقات أعمال تصمد أمامها

· · Windows, إدارة الطاقة, تطوير Windows, تطبيقات الأعمال, التحكّم بالأجهزة, استكشاف الأخطاء, Win32 API

«أغلقت الحاسوب المحمول، وفتحته صباح اليوم التالي، فإذا تطبيق الأعمال مليء بالأخطاء.» «تطبيق مراقبة المعدّات يُسقط البيانات فقط بعد الغداء.» «الأداة المقيمة التي تصدِّر إلى Excel تتوقّف أحياناً بخطأ اتّصال.» ── هذه التذاكر تشترك في مشتبه واحد. السكون.

تطبيقات الأعمال من عصر كانت فيه الحواسيب المكتبيّة هي السائدة كُتبت على افتراض غير معلَن أنّ «الحاسوب يبقى شغّالاً». ساحة المعركة الرئيسة اليوم هي الحاسوب المحمول، وهو ينام افتراضيّاً بعد دقائق قليلة من الخمول. على جهاز قادر على Modern Standby، تغيّرت دلالات السكون نفسها عن النموذج التقليديّ. موجَّه إلى المطوِّرين الذين يكتبون تطبيقات أعمال وبرمجيّات التحكّم بالمعدّات على Windows، ينظِّم هذا المقال، من المصادر الأوّليّة، ما يُشعر به نظام التشغيل التطبيق قبل السكون وبعده، وما الذي ينكسر، وكيف تكتب تطبيقاً يصمد أمام الاستئناف.

1. الخلاصة أوّلاً

  • السكون حدث «لا حقّ للتطبيق في رفضه». تُشعَر قبيل ذلك بـWM_POWERBROADCAST (PBT_APMSUSPEND)، لكنّ مهلة السماح نحو ثانيتين، وعند تعليق طارئ لا يصل الإشعار أصلاً.12
  • عند الاستئناف من التعليق يصل PBT_APMRESUMEAUTOMATIC، وعند استئناف بدأَه المستخدم يصل PBT_APMRESUMESUSPEND أيضاً. العمل اللازم كإعادة الاتّصال ينتمي إلى الأوّل كقاعدة. غير أنّ الدخول إلى خمول الطاقة المنخفضة في Modern Standby والخروج منه لا يتوافقان دائماً مع هذه الإشعارات، لذا عالج الإشعارات بوصفها عوناً.34
  • صمِّم على افتراض أنّ اتّصالات TCP والمنافذ التسلسليّة ومقابض الأجهزة لا تصمد عبر الاستئناف. منطق إعادة الاتّصال الذي يعيد بناءها عند إشعار الاستئناف أو خطأ الاتّصال هو الحدث الرئيس.
  • راقب المؤقِّتات ومعالجة الوقت. العمل الدوريّ يتوقّف أثناء السكون، وكيفيّة إطلاقه فور الاستئناف تختلف حسب واجهة المؤقِّت وبيئة التشغيل. يحدث أيضاً «قفزة هائلة في الوقت المنقضي»، لذا النهج الآمن إعادة بناء الجدول عند الاستئناف.
  • اكبح السكون صراحةً للمدد التي لا تريد أن يقطعها السكون. استخدم SetThreadExecutionState (ES_SYSTEM_REQUIRED) أو طلب طاقة (PowerSetRequest)، وامسحه دائماً عند انتهاء العمل.45
  • على جهاز Modern Standby ما زال النظام يعمل بشكل متقطّع أثناء السكون، لكن تطبيقات سطح المكتب تُعلَّق. لا يمكنك التمسّك بتوقّع أنّ «تطبيقنا ينبغي أن يستمرّ بالعمل أثناء السكون».6
  • أدوات التحقيق القياسيّة هي powercfg ‏(/requests و/lastwake و/sleepstudy) وKernel-Power في سجلّ الأحداث.

2. ماذا يحدث حول السكون ── تدفّق أحداث الطاقة

يبثّ نظام التشغيل تغيّرات حالة الطاقة إلى كلّ تطبيق كرسالة WM_POWERBROADCAST.2 ثمّة ثلاثة أحداث رئيسة تتعلّق بالسكون والاستئناف.

الحدث المعنى
PBT_APMSUSPEND على وشك الدخول في السكون (الفرصة الأخيرة للتهيئة)
PBT_APMRESUMEAUTOMATIC استأنف (يصل دائماً عند الاستئناف)
PBT_APMRESUMESUSPEND استئناف سببه فعل مستخدم (هذا مشروط)

PBT_APMSUSPEND هو الإشعار قبيل السكون مباشرةً، وهنا يمكنك التهيئة بإغلاق الملفّات وحفظ الحالة. غير أنّ هناك شرطين. الأوّل، الوقت المسموح للمعالجة نحو ثانيتين لكلّ تطبيق، وإن تجاوزته يتابع النظام دون انتظار.1 الثاني، عند تعليق طارئ كنفاد البطاريّة الحرِج، ينام فوراً بلا إشعار مسبق.2 تصميم «يجب أن ينتهي قبل السكون» لا يصمد. عالج الإشعار بوصفه فرصة «افعله إن أدركته»، وضَع العمل الرئيس في جانب الاستئناف.

جانب الاستئناف مرحلتان. PBT_APMRESUMEAUTOMATIC يصل عند الاستئناف من انتقال تعليق. فوق ذلك، إن استأنف الجهاز بفعل مستخدم كزرّ الطاقة أو ضغط مفتاح (أو اكتُشفت حضور المستخدم لاحقاً)، يتبع PBT_APMRESUMESUSPEND. بالمقابل، استئناف غير مراقب لإيقاظ بعيد عبر الشبكة أو للصيانة يسلِّم PBT_APMRESUMEAUTOMATIC فقط.3 هاتان المرحلتان نفسهما تلميح لكيفيّة تقسيم العمل ── افعل الاستعادة الآليّة كإعادة بناء الاتّصالات على PBT_APMRESUMEAUTOMATIC، وافعل الأفعال المواجهة للمستخدم كتحديثات الشاشة أو مِحَثّ إعادة تسجيل الدخول على PBT_APMRESUMESUSPEND.

تدفّق الإشعار للسكون والاستئنافيصل PBT_APMSUSPEND قبيل السكون بمهلة نحو ثانيتين؛ عند الاستئناف يصل PBT_APMRESUMEAUTOMATIC دائماً، ويتبع PBT_APMRESUMESUSPEND فقط لاستئناف بدأَه المستخدمالتطبيقنظام التشغيلالتطبيقنظام التشغيلالسكون(الشيفرة لا تعمل)PBT_APMSUSPEND(مهلة نحو ثانيتين)احفظ الحالة وأغلق الاتّصالاتPBT_APMRESUMEAUTOMATIC(يصل عند الاستئناف)أعد الاتّصال واستعد الحالةPBT_APMRESUMESUSPEND(استئناف المستخدم فقط)تحديثات الشاشة وعمل مواجه للمستخدم

الشكل 1: الإشعارات ليست سوى «كلمة قبيل ذلك، وكلمة أو كلمتين بعد الاستئناف». نجم الاستعادة هو العمل في جانب الاستئناف.

الفرق بين السكون العاديّ والتعليق الطارئالسكون العاديّ يسلِّم PBT_APMSUSPEND قبيل ذلك بنحو ثانيتين للتهيئة، أمّا التعليق الطارئ كنفاد البطاريّة الحرِج فيتوقّف بلا إشعار مسبق، لذا تصميم يعتمد على الإشعار المسبق لا يصمدالسكون العاديّPBT_APMSUSPEND(مهلة نحو ثانيتين)هيِّئ، ثمّ توقّفتعليق طارئ(نفاد البطاريّة الحرِج)توقّف بلا إشعار مسبقتصميم يفترض وصول الإشعار لا يصمد

الشكل 2: التعليق الطارئ يأتي بلا إنذار. لذا التهيئة «مكافأة إن أدركتها»، والعمل الرئيس يذهب إلى جانب الاستئناف.

لاحظ أنّ WM_POWERBROADCAST لا يميِّز نوع حالة الطاقة المنخفضة (سكون مقابل إسبات).4 التجريد الصحيح للتطبيق معاملته نوعاً واحداً من الأحداث: «توقّف، ثمّ عاد». الخدمات والتطبيقات الطرفيّة بلا نافذة يمكنها استقبال الإشعارات نفسها باستخدام RegisterSuspendResumeNotification بشكل ردّ نداء (DEVICE_NOTIFY_CALLBACK).7

تقسيم العمل عبر مرحلتَي الاستئنافضَع الاستعادة الآليّة كإعادة الاتّصال على PBT_APMRESUMEAUTOMATIC الذي يصل عند الاستئناف؛ وضَع العمل المواجه للمستخدم كتحديثات الشاشة أو مِحَثّ إعادة تسجيل الدخول على PBT_APMRESUMESUSPEND الذي يصل فقط عند استئناف بدأَه المستخدمPBT_APMRESUMEAUTOMATIC(عند الاستئناف)استعادة آليّةPBT_APMRESUMESUSPEND(استئناف المستخدم)عمل مواجه للمستخدمأعد الاتّصال وأعد فتح المقابضتحديثات الشاشة ومِحَثّ إعادة الدخول

الشكل 3: الأخير لا يصل عند استئناف غير مراقب، لذا وضع الاستعادة اللازمة على الأخير سيُفوِّتها.

3. Modern Standby ── معنى «السكون» تغيّر

حقيقة حديثة أخرى ينبغي استيعابها هي Modern Standby. سكون S3 التقليديّ كان نموذجاً بسيطاً «أوقف المنظومة ككلّ»؛ السكون على جهاز Modern Standby نموذج شبيه بالهاتف الذكيّ فيه النظام يستمرّ بالعمل بشكل متقطّع بعد إطفاء الشاشة.

ما يهمّ تطبيق الأعمال هنا هو أنّ تطبيقات سطح المكتب تُعلَّق بواسطة Desktop Activity Moderator (DAM) في المرحلة الأولى من الدخول في السكون.6 النظام نفسه ما زال يعمل من حين لآخر لإبقاء الشبكة واستقبال الإشعارات، لكن المكوِّنات التي تستفيد من ذلك هي التي تشارك في هذه الآليّة ── شيفرة تطبيق سطح المكتب العاديّة لا تعمل. لذا من منظور المطوِّر الاستنتاج واحد لـ Modern Standby ولـ S3 ── صمِّم على افتراض أنّ شيفرتك لا تعمل أثناء السكون.

الفرق بين السكون التقليديّ وModern Standbyسكون S3 التقليديّ يوقف المنظومة ككلّ، بينما تحت Modern Standby ما زال النظام يعمل بشكل متقطّع بعد إطفاء الشاشة. تطبيقات سطح المكتب تُعلَّق بواسطة DAM في الحالتين، لذا شيفرة التطبيق لا تعملسكون S3 التقليديّ: المنظومة كلّها تتوقّفشيفرة التطبيق لا تعملModern Standby: النظام يعمل بشكل متقطّعتطبيقات سطح المكتب تُعلَّق بـ DAM

الشكل 4: تغيّر النموذج، لكن لتطبيق سطح المكتب الاستنتاج واحد: «لا يمكنك العمل أثناء السكون».

تحذير آخر هو مدى ضآلة ما يمكنك الاعتماد عليه من الإشعارات. تحت Modern Standby، الدخول إلى خمول الطاقة المنخفضة والخروج منه لا يتوافقان مع انتقال التعليق التقليديّ، وقد يكون الاتّصال مكسوراً أصلاً دون أن يصل إشعار قطّ. عالج إشعار الاستئناف بوصفه عوناً، وضَع إعادة الاتّصال التي يطلقها كشف الخطأ (الفصل 5) على مسار الاستعادة الرئيس.

فرق آخر هو الإحساس «الزلق» للسلوك. بلوغ أعماق السكون يتمّ على مراحل، وتوقيت القطع والتوقّف ليس حادّاً كما تحت S3. التمييز بين «الشاشة انطفأت فحسب» و«نام» يصعب على المستخدم رؤيته أيضاً، لذا عندما تأخذ عرَضاً تحتاج إلى تأكيد «هل أغلقوا الغطاء» و«كم دقيقة تُرك خاملاً».

4. ما الذي ينكسر ── أعراض كلاسيكيّة

اتّصال TCP ميّت. أثناء السكون يعامل الطرف الآخر وNAT وجدران الحماية صمتك مهلةً ويسقطون الاتّصال. والأسوأ أنّ المقبس في هذا الجانب لا يعلم بالخطأ، لذا يفشل فقط عندما ترسل أو تستقبل بعد الاستئناف. أو أسوأ بعد، انتظار استقبال لا يُخطئ أصلاً (لذلك تحتاج إلى keepalive). اتّصالات قواعد البيانات وWebSockets لها الشكل نفسه.

مقابض المنفذ التسلسليّ وأجهزة USB تصبح غير صالحة. جهاز متّصل بـUSB يمكن أن يبدو، عند الاستئناف، كأنّه «فُصل وأُعيد توصيله» مرّة، ويبدأ المقبض الذي كان مفتوحاً بإرجاع أخطاء. هذا النمط النموذجيّ لتطبيق تحكّم بالمعدّات «يحصل على خطأ اتّصال فقط بعد الغداء». تصميم إعادة الاتّصال مشمول أيضاً في مقال الاتّصال التسلسليّ.

استمراريّة الوقت تنكسر. العمل المدفوع بالمؤقِّت مثل «استطلع كلّ 10 ثوانٍ» لا يُطلَق أثناء السكون. كيفيّة إطلاقه فور الاستئناف (العمل المستحقّ المنتهي يُطلَق مرّة فوراً، لا يحدث شيء حتّى الدورة التالية، وهكذا) تختلف حسب واجهة المؤقِّت وبيئة التشغيل التي تستخدمها، لذا لا تترك معالجة الدقّات الفائتة للسلوك الضمنيّ ── النهج الآمن إعادة بناء الجدول عند إشعار الاستئناف. كذلك، حسابات الوقت المنقضي (الفرق عن الختم الزمنيّ السابق) تصبح فجأةً «ما يعادل 8 ساعات»، وتنكسر حسابات المتوسّط أو أحكام المهلة. العمل المجدول مثل «شغِّل كلّ ليلة الساعة 2 صباحاً» ببساطة لا يعمل إن كان الحاسوب نائماً في ذلك الوقت (أيقظه بميزة الإيقاظ من السكون في جدولة المهام إن احتجت إليها).

ثلاثة أشكال تنكسر فيها استمراريّة الوقتالعمل الدوريّ يتوقّف أثناء السكون والإطلاق بعد الاستئناف يختلف حسب الواجهة، لذا أعد بناء الجدول عند الاستئناف؛ الفرق عن الختم الزمنيّ السابق يصبح هائلاً بعد الاستئناف فاحمه؛ العمل المجدول لا يعمل إن كان الجهاز نائماً، فانظر إيقاظ جدولة المهام من السكونعمل دوريّ: يتوقّفأعد بناء الجدولوقت منقضٍ: ينفجراحمِ الفروقات الشاذّةمجدول: لم يعمل قطّإيقاظ من السكون

الشكل 5: اكتب معالجة المؤقِّت والوقت على افتراض أنّ «الوقت يقفز». لكلّ من الأشكال الثلاثة نوع إجراء مضادّ.

ثلاثة أشياء تنكسر عبر السكونعبر السكون، يكون اتّصال TCP قد أسقطته مهلة في الطرف الآخر، ومقبض جهاز USB يُبطَل كإعادة اتّصال، والعمل القائم على الوقت المنقضي يلاحظ قفزة زمنيّة هائلة. استعد كلاً بإعادة الاتّصال وإعادة الفتح وحماية الفرقفترة السكونTCP: الطرف أسقطهUSB أم وقت منقضٍ؟USB: المقبض غير صالحوقت منقضٍ: قفزةاكتشف + أعد الاتّصالأعد فتح الجهازاحمِ الفروقات الشاذّة

الشكل 6: ما ينكسر يقع في ثلاث عائلات ── «الاتّصالات» و«المقابض» و«استمراريّة الوقت» ── ولكلّ منها نوع استعادة مستقرّ.

إعادة المصادقة على الموارد المشتركة. محرّكات الشبكة والشبكات الافتراضيّة الخاصّة غالباً تحتاج إلى إعادة إنشائها بعد الاستئناف، وثمّة «وادٍ عند البدء» من بضع ثوانٍ إلى عشرات الثواني فور الاستئناف تفشل فيه عمليّات الوصول. من الأسلم ألا تعيد محاولة كلّ شيء دفعة واحدة فور الاستئناف، بل تنتظر قليلاً وتعيد المحاولة على مراحل.

5. بناء تطبيقات تصمد أمام الاستئناف

المبدأ شيء واحد. افترض أنّ «الاتّصالات والمقابض لا تصمد عبر السكون»، وهيكل التطبيق بحيث تستطيع الاستعادة دائماً.

اكتشف الاستئناف واستعد. عندما تستقبل نافذة المستوى الأعلى في WM_POWERBROADCAST حدث PBT_APMRESUMEAUTOMATIC، تخلَّص من الاتّصالات التي تحملها وأعد بناءها. النقطة هي عدم الاعتماد على إشعار الاستئناف وحده. الإشعارات الفائتة والاتّصال الذي يحدث قبل الإشعار كلاهما واقع، لذا اقرنه دائماً بمسار «يعيد الاتّصال عندما يُكتشف خطأ اتّصال»، وعالج إشعار الاستئناف بوصفه محفِّزاً يبدأ ذلك مبكّراً فحسب.

// C#: funnel both the resume notification and communication errors into the same reconnect path
protected override void WndProc(ref Message m)
{
    const int WM_POWERBROADCAST = 0x0218;
    const int PBT_APMRESUMEAUTOMATIC = 0x0012;
    if (m.Msg == WM_POWERBROADCAST && (int)m.WParam == PBT_APMRESUMEAUTOMATIC)
    {
        _connectionManager.RequestReconnect();   // idempotent reconnect request
    }
    base.WndProc(ref m);
}

اجعل عمل إعادة الاتّصال نفسه متكافئاً (آمناً مهما استُدعي مرّات)، وأعد المحاولة عند الفشل بتمهّل أسيّ، وفي الحالة المستقرّة اكتشف اتّصالاً ميّتاً مبكّراً بـkeepalive ── اجمع هذه الثلاث كمجموعة، وستصمد ليس أمام الاستئناف من السكون فحسب بل أيضاً أمام سقوط شبكة وجيز أو إعادة تشغيل جهاز.

تصميم إعادة اتّصال يصمد أمام الاستئنافإشعار الاستئناف وخطأ الاتّصال وفشل keepalive كلّها تصبّ في عمل إعادة اتّصال متكافئ واحد، يعيد المحاولة بتمهّل أسيّ عند الفشلنعملاإشعار الاستئناف(PBT_APMRESUMEAUTOMATIC)عمل إعادة اتّصال متكافئكشف خطأ الاتّصالفشل Keepaliveنجح؟عودة إلى التشغيل العاديّأعد المحاولة بعد تمهّل أسيّ

الشكل 7: ركِّز إعادة الاتّصال في مسار متكافئ واحد، وادخل الطريق نفسه من إشعار الاستئناف أو كشف الخطأ أو الـkeepalive.

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

اكبح السكون صراحةً للمدد التي لا تريد أن يقطعها السكون. أثناء عمل يجب ألا يقطعه السكون ── ترحيل بيانات، واتّصال متواصل مع جهاز، وما شابه ── يمكنك إبقاء النظام مستيقظاً بـSetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) (أضِف ES_DISPLAY_REQUIRED إن أردت إبقاء الشاشة أيضاً).45 طريقة أفضل سلوكاً هي واجهة طلب الطاقة (PowerCreateRequest + PowerSetRequest)، التي يمكنها إرفاق سلسلة سبب، وسيعرض powercfg /requests بعدها «من يحجبه ولماذا».8 لاحظ أنّ الكبح عبر SetThreadExecutionState هو لكلّ مؤشّر ترابط، وتمسحه من مؤشّر الترابط نفسه الذي ضبطه. للعمل الذي يغيّر مؤشّرات الترابط، كـasync/await، استخدم جانب طلب الطاقة الذي يُدار بمقبض. ثمّة تحذيرات. الأوّل، ما تكبحه هذه هو السكون التلقائيّ الناتج عن الخمول. لا تستطيع إيقاف فعل مستخدم صريح كإغلاق الغطاء أو اختيار السكون من قائمة ابدأ، لذا لا يمكنك تخطّي تصميم إعادة الاتّصال في هذا الفصل حتّى أثناء الكبح. الثاني، على البطاريّة على جهاز Modern Standby، تُقطع طلبات الطاقة هذه أيضاً بعد مدّة من انقضاء مهلة السكون. العمل الذي لا يمكن مقاطعته يجب ضمانه بطاقة تيار متردّد أو بالتشغيل.8 الثالث، امسحه دائماً عند انتهاء العمل. المسح المنسيّ يصبح خطأً جديداً: «هذا الحاسوب، لسبب ما، لن ينام».

وسيلتان لكبح السكونسواء استخدمت SetThreadExecutionState المريحة أو واجهة طلب الطاقة التي يمكنها إرفاق سلسلة سبب وتظهر للمسؤول عبر powercfg، امسحها دائماً عند انتهاء العملمدّة عمل يجب ألا يقطعها السكونSetThreadExecutionStateطلب طاقة(PowerSetRequest)مريح ── أعلام فقطمع سبب ── ظاهر في powercfgامسحه دائماً عند انتهاء العمل

الشكل 8: لأيّ من الوسيلتين، «امسحه عندما تنتهي» شرط مطلق. طلب طاقة يمكنه إظهار السبب ألطف للتشغيل.

الخدمات والتطبيقات بلا نافذة تستقبل إشعارات ردّ النداء بـRegisterSuspendResumeNotification (DEVICE_NOTIFY_CALLBACK).7 إن كان التشغيل المتواصل متطلَّباً حقيقيّاً، الحلّ الجذريّ إعادة النظر في تصميم يُبقي العمل مقيماً على حاسوب عميل ينام، ونقله إلى جانب الخادم أو إلى جهاز يُشغَّل بلا سكون.

6. التحقيق ── powercfg وسجلّ الأحداث

التحقيق حول الطاقة تخدمه جيّداً الأدوات التي تشحن مع نظام التشغيل.

  • لن ينام: powercfg /requests يسرد العمليّات والتعريفات التي أصدرت طلب طاقة. «التطبيق نسي مسح SetThreadExecutionState» يظهر هنا أيضاً.
  • يستيقظ من تلقاء نفسه: powercfg /lastwake يعرض أحدث سبب إيقاظ، وpowercfg /waketimers يعرض المؤقِّتات المحجوزة حالياً لإيقاظ الجهاز.
  • جودة Modern Standby: powercfg /sleepstudy يولِّد تقريراً عن استهلاك الطاقة والنشاط لكلّ فترة سكون.9
  • تأكيد الخطّ الزمنيّ: مصدر Kernel-Power في سجلّ الأحداث (النظام) يحتفظ بسجلّات الدخول في السكون والاستئناف. مطابقتها مع سجلّ التطبيق تتيح لك تأكيداً موضوعيّاً لما إذا «كان ثمّة استئناف قبيل الخطأ».
ربط أعراض أعطال الطاقة بأوامر التحقيقلعَرَض لن-ينام، اعثر من يمسك طلب طاقة بـ powercfg /requests؛ لعَرَض يستيقظ-من-تلقاء-نفسه، اعثر سبب الإيقاظ بـ /lastwake و/waketimers؛ للخطّ الزمنيّ استخدم Kernel-Power في سجلّ الأحداثلن ينامpowercfg /requestsيستيقظ من تلقاء نفسهpowercfg /lastwake و/waketimersأريد تأكيد الخطّ الزمنيّKernel-Power في سجلّ الأحداثكبح سكون منسيّ يظهر أيضاً

الشكل 9: الأعراض ترتبط بأوامر التحقيق في ثلاث عائلات. أكِّد أوّلاً «هل نام للتوّ»، ثمّ قسِّم.

في معالجة التذاكر، مجرّد السؤال أوّلاً «هل كان الحاسوب نائماً قبيل ذلك (هل أغلقوا الغطاء)» يسرِّع العزل كثيراً.

7. الخلاصة

  • السكون لا يمكن رفضه. الإشعار المسبق (PBT_APMSUSPEND) أفضل جهد بمهلة نحو ثانيتين، ولا يأتي في الطوارئ. ضَع التصميم الرئيس في جانب الاستئناف.
  • إشعارات الاستئناف هي PBT_APMRESUMEAUTOMATIC (عند الاستئناف من التعليق) + PBT_APMRESUMESUSPEND (عند فعل مستخدم). أبقِ إعادة الاتّصال المدفوعة بالخطأ على المسار الرئيس لحالة عدم وصول الإشعار.
  • افترض أنّ الاتّصالات والمقابض لا تصمد عبر الاستئناف، ونفِّذ المجموعة الثلاثيّة من إعادة اتّصال متكافئة + تمهّل أسيّ + keepalive.
  • ضَع حماية ضدّ «الفروقات الشاذّة» على العمل القائم على الوقت المنقضي. صمِّم العمل المجدول على افتراض أنّه لا يعمل أثناء السكون.
  • للمدد التي يجب ألا يقطعها السكون، اكبح السكون صراحةً بـSetThreadExecutionState أو طلب طاقة، وامسحه دائماً عندما تنتهي.
  • التحقيق هو powercfg ‏(/requests و/lastwake و/sleepstudy) وسجلّ أحداث Kernel-Power. في معالجة التذاكر، اسأل أوّلاً «هل نام قبيل ذلك».

من منظور التطبيق، السكون حدث فيه «يقفز الوقت بلا إنذار، وتُقطع الاتّصالات بالمحيط، ثمّ يعود». ما إذا كنت قد نسجت ذلك في التصميم بوصفه جزءاً من الحياة اليوميّة، لا بوصفه وضعاً شاذاً، هو ما يفصل استقرار تطبيق أعمال في عصر الحاسوب المحمول.

مقالات ذات صلة

مجالات الاستشارة ذات الصلة

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

روابط مرجعيّة

  1. Microsoft Learn, PBT_APMSUSPEND event. حول كون هذا الحدث الذي يصل قبيل دخول الحاسوب حالة التعليق؛ وحول توقُّع أن ينهي التطبيق العمل اللازم لحفظ البيانات؛ وحول سماح النظام بنحو ثانيتين لمعالجة هذا الإشعار، مع إمكان مقاطعة تطبيق يستمرّ أبعد من ذلك.  2

  2. Microsoft Learn, System Power Management Events. حول بثّ النظام تغيّرات وضع التشغيل كالسكون مسبقاً؛ وحول إشعار PBT_APMSUSPEND قبل سكون الخمول حتّى تتمكّن من التهيئة بإغلاق الملفّات وحفظ البيانات؛ وحول عدم إعطاء تعليق طارئ (البطاريّة الحرِجة وما شابه) إشعاراً مسبقاً؛ وحول السماح لمعالجة هذه الرسالة بثانيتين كحدّ أقصى لكلّ تطبيق وقطعها بعد المهلة؛ وحول إشعار كلّ تطبيق عند الاستئناف.  2 3

  3. Microsoft Learn, PBT_APMRESUMESUSPEND event. حول إرساله بعد PBT_APMRESUMEAUTOMATIC عند استئناف بدأَه المستخدم أو عند اكتشاف إدخال مستخدم لاحقاً؛ وحول إرسال PBT_APMRESUMEAUTOMATIC فقط لاستئناف من سبب خارجيّ كإيقاظ بعيد؛ وحول توقُّع أن يعيد التطبيق فتح الملفّات المغلقة وقت السكون وأن يتهيّأ لإدخال المستخدم.  2

  4. Microsoft Learn, WM_POWERBROADCAST message. حول إرسال PBT_APMRESUMEAUTOMATIC دائماً عند الاستئناف، مع إرسال PBT_APMRESUMESUSPEND أيضاً عند استئناف من إدخال مستخدم؛ وحول عدم تمييز هذه الرسالة نوع حالة الطاقة المنخفضة؛ وحول تسجيل تفاصيل انتقالات حالة الطاقة في سجلّ أحداث النظام؛ وحول استدعاء SetThreadExecutionState لمنع النظام من دخول حالة طاقة منخفضة.  2 3 4

  5. Microsoft Learn, SetThreadExecutionState function (winbase.h). حول قدرة ES_SYSTEM_REQUIRED وES_DISPLAY_REQUIRED على كبح سكون خمول النظام وإطفاء الشاشة؛ وحول إعلان كبح متواصل بـES_CONTINUOUS ومسحه باستدعاء ES_CONTINUOUS وحده عندما تنتهي.  2

  6. Microsoft Learn, Prepare software for modern standby. حول قيام Desktop Activity Moderator (DAM) بتعليق تطبيقات سطح المكتب في المرحلة الأولى من الانتقال إلى Modern Standby؛ وحول انتقال النظام بعدها على مراحل إلى طور طاقة منخفضة وطور مرونة، مع عمل المكوِّنات المسموح بها فقط بشكل متقطّع.  2

  7. Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). حول كون هذه الواجهة التي تسجِّل لاستقبال إشعارات التعليق/الاستئناف، وحول تحديد DEVICE_NOTIFY_CALLBACK حتّى يستطيع تطبيق أو خدمة بلا نافذة استقبال الإشعار عبر ردّ نداء إضافةً إلى تسليم الرسالة إلى مقبض نافذة.  2

  8. Microsoft Learn, PowerSetRequest function (winbase.h). حول إمكان ضبط نوع طلب كبقاء النظام أو الشاشة مستيقظين على كائن طلب طاقة يُنشأ بـPowerCreateRequest؛ وحول إمكان إرفاق سلسلة سبب تشخيصيّة؛ وحول إمكان تعداد طلبات الطاقة القائمة بـpowercfg /requests.  2

  9. Microsoft Learn, Modern standby SleepStudy. حول تمكين التقرير الذي يولِّده powercfg /sleepstudy من فحص، لكلّ فترة Modern Standby، استهلاك الطاقة والنشاط وسبب الإيقاظ (زرّ الطاقة، إدخال مستخدم، مؤقِّت إيقاظ، وما شابه). 

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

هل يستطيع التطبيق أن يعلم بالسكون مسبقاً ويرفضه؟
على Windows الحالي يمكنك استقبال الإشعار، لكن لا يمكنك الرفض. قبيل السكون مباشرةً، تصل رسالة WM_POWERBROADCAST بحدث PBT_APMSUSPEND، وهنا يمكنك التهيئة بإغلاق الملفّات وحفظ الحالة، لكن الوقت المسموح للمعالجة نحو ثانيتين لكلّ تطبيق، وإن تجاوزته يتابع النظام دون انتظار. عند تعليق طارئ كنفاد البطاريّة الحرِج، لا يصل الإشعار المسبق أصلاً. لذا فإنّ تصميماً «يجب أن ينتهي قبل السكون» لا يصمد؛ تحتاج تصميماً يستطيع الاستعادة عند الاستئناف مهما جاء القطع. لمدّة عمل لا تريد حقّاً أن يقطعها السكون، اكبح السكون صراحةً بـ SetThreadExecutionState أو بطلب طاقة (PowerSetRequest).
كيف أكتشف أنّ الجهاز قد استأنف؟
إن كان للتطبيق نافذة، عالج WM_POWERBROADCAST. عند الاستئناف من التعليق يصل PBT_APMRESUMEAUTOMATIC، وإن كان الاستئناف بفعل مستخدم (زرّ الطاقة أو ضغط مفتاح)، يتبعه PBT_APMRESUMESUSPEND. الاستئناف غير المراقب الذي يعود إلى السكون فوراً يسلِّم PBT_APMRESUMEAUTOMATIC فقط، لذا التقسيم الأساسيّ هو وضع العمل اللازم كإعادة الاتّصال في جانب PBT_APMRESUMEAUTOMATIC، والعمل المواجه للمستخدم كتحديثات الشاشة في جانب PBT_APMRESUMESUSPEND. الخدمات والتطبيقات الطرفيّة بلا نافذة يمكنها استقبال الإشعارات نفسها عبر ردّ نداء باستخدام RegisterSuspendResumeNotification مع DEVICE_NOTIFY_CALLBACK.
هل يمكنني إبقاء التطبيق يعمل أثناء السكون؟
كقاعدة، لا. أثناء السكون يتوقّف تنفيذ المعالج نفسه (على جهاز Modern Standby تُعلَّق تطبيقات سطح المكتب بواسطة Desktop Activity Moderator)، ولا تعمل شيفرة التطبيق. ثمّة خياران. الأوّل كبح السكون فقط أثناء سير العمل. تحديد ES_SYSTEM_REQUIRED مع SetThreadExecutionState، أو إصدار طلب طاقة بـ PowerCreateRequest/PowerSetRequest، يكبح السكون التلقائيّ الناتج عن الخمول لتلك المدّة (يمكنك التحقّق بـ powercfg /requests). ذلك ما زال لا يوقف فعلاً صريحاً كإغلاق المستخدم للغطاء، لذا ما زلت تحتاج الاستعداد للاستئناف حتّى أثناء الكبح. الثاني قبول السكون والتصميم على «اللحاق بعد الاستئناف». للعمل المجدول كدفعة ليليّة، يمكنك أيضاً إيقاظ الحاسوب بميزة «تنشيط الحاسوب لتشغيل هذه المهمّة» في جدولة المهام. العمل الذي يحتاج حقّاً إلى التشغيل المتواصل ينتمي إلى خادم أو خدمة مُعدَّة لعدم السكون.
لماذا تتوقّف اتّصالات TCP والمنافذ التسلسليّة عن العمل بعد الاستئناف؟
لأنّ محوّلات الشبكة وأجهزة USB تدخل أيضاً حالة طاقة منخفضة أثناء السكون. اتّصال TCP يكون الطرف الآخر أو مهلة NAT أو جدار الحماية قد أسقطه أصلاً، والإرسال/الاستقبال بعد الاستئناف يُرجع خطأً (غالباً لا تلاحظ حتّى يحدث الخطأ). محوّلات USB-إلى-تسلسلي وما شابه تُعامَل أحياناً كإزالة جهاز وإعادة إدخاله عند الاستئناف، فيصبح المقبض الذي كان مفتوحاً غير صالح. لكليهما، الافتراض الصحيح هو أنّ «المقابض والاتّصالات لا تصمد عبر الاستئناف»، والجواب الصحيح تنفيذ منطق إعادة اتّصال يعيد بناء الاتّصال عند إشعار الاستئناف أو خطأ الاتّصال. الجمع بين keepalive دوريّ وإعادة محاولات بتمهّل أسيّ عند الفشل هو النمط المستقرّ.
كيف أحقّق في سكون غير متوقَّع أو استئناف غير متوقَّع؟
أمر powercfg هو الأداة الأولى. في اتّجاه «لن ينام»، يسرد powercfg /requests أيّ العمليّات والتعريفات أصدرت طلب طاقة يحجب السكون. في اتّجاه «يستيقظ من تلقاء نفسه»، يعرض powercfg /lastwake أحدث سبب إيقاظ وpowercfg /waketimers المؤقِّتات المحجوزة حالياً لإيقاظ الجهاز. على جهاز Modern Standby، يُنتج powercfg /sleepstudy تقريراً عن الاستهلاك والنشاط أثناء السكون. تاريخ السكون والاستئناف يُسجَّل أيضاً في سجلّ الأحداث (مصدر Kernel-Power في سجلّ النظام)، لذا يمكنك التأكيد على خطّ زمنيّ «متى نام، ومتى ولماذا استيقظ».

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

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

العودة إلى المدونة