स्लीप से रिज़्यूम पर टूटने वाले ऐप — Windows पावर इवेंट कैसे काम करते हैं और उनसे बचने वाले व्यावसायिक ऐप कैसे बनाएँ
· Go Komura · Windows, पावर प्रबंधन, Windows विकास, व्यावसायिक ऐप, उपकरण नियंत्रण, समस्या निवारण, Win32 API
“मैंने लैपटॉप बंद किया, अगली सुबह खोला, और व्यावसायिक ऐप त्रुटियों से भरा था।” “उपकरण-निगरानी ऐप केवल दोपहर के बाद डेटा गिराती है।” “Excel में निर्यात करने वाला रेज़िडेंट टूल कभी-कभी कनेक्शन त्रुटि पर रुक जाता है।” — इन टिकटों का एक ही संदिग्ध है। स्लीप।
उस युग के व्यावसायिक ऐप जब डेस्कटॉप PC मुख्यधारा थे, इस अनकही धारणा पर लिखे गए कि “PC चालू रहता है”। आज का मुख्य युद्धक्षेत्र लैपटॉप है, और डिफ़ॉल्ट पर कुछ मिनट आइडल के बाद वह सो जाता है। Modern Standby-सक्षम मशीन पर स्लीप के अर्थ स्वयं पारंपरिक मॉडल से बदल गए हैं। Windows पर व्यावसायिक ऐप और उपकरण-नियंत्रण सॉफ़्टवेयर लिखने वाले डेवलपरों के लिए, यह लेख प्राथमिक स्रोतों से व्यवस्थित करता है कि स्लीप के पहले और बाद OS ऐप को क्या सूचित करता है, क्या टूटता है, और रिज़्यूम से बचने वाला ऐप कैसे लिखें।
1. निष्कर्ष पहले
- स्लीप वह इवेंट है जिसे ऐप को “अस्वीकार करने का अधिकार नहीं”। ठीक पहले
WM_POWERBROADCAST(PBT_APMSUSPEND) से सूचना मिलती है, पर छूट लगभग 2 सेकंड है, और आपात सस्पेंड पर सूचना आती ही नहीं।12 - सस्पेंड से रिज़्यूम पर PBT_APMRESUMEAUTOMATIC आता है, और उपयोगकर्ता-प्रेरित रिज़्यूम पर PBT_APMRESUMESUSPEND भी आता है। पुनः-कनेक्ट जैसे आवश्यक काम नियमतः पहले वाले पर रखें। Modern Standby के निम्न-पावर आइडल में प्रवेश और निकास इन सूचनाओं से हमेशा मेल नहीं खाते, इसलिए सूचनाओं को सहायक मानें।34
- इस धारणा पर डिज़ाइन करें कि TCP कनेक्शन, सीरियल पोर्ट, और डिवाइस हैंडल रिज़्यूम पार नहीं बचते। रिज़्यूम सूचना या संचार त्रुटि पर उन्हें दोबारा बनाने वाला पुनः-कनेक्ट लॉजिक मुख्य घटना है।
- टाइमर और समय के सँभाल पर नज़र रखें। आवधिक काम स्लीप के दौरान रुकता है, और रिज़्यूम के तुरंत बाद कैसे फायर होता है यह टाइमर API और रनटाइम से भिन्न होता है। “बीते समय में विशाल छलांग” भी होती है, इसलिए सुरक्षित तरीका है रिज़्यूम पर अनुसूची दोबारा बनाना।
- जिन अंतरालों में स्लीप नहीं चाहिए, स्लीप स्पष्ट रूप से दबाएँ।
SetThreadExecutionState(ES_SYSTEM_REQUIRED) या पावर रिक्वेस्ट (PowerSetRequest) उपयोग करें, और काम खत्म होने पर हमेशा साफ़ करें।45 - Modern Standby मशीन पर सिस्टम स्लीप के दौरान भी रुक-रुक कर चलता है, पर डेस्कटॉप ऐप रुके रहते हैं। यह अपेक्षा न रखें कि “हमारा ऐप स्लीप के दौरान चलता रहे”।6
- मानक जाँच उपकरण
powercfg(/requests, /lastwake, /sleepstudy) और इवेंट लॉग का Kernel-Power हैं।
2. स्लीप के आसपास क्या होता है — पावर इवेंट का प्रवाह
OS पावर-अवस्था परिवर्तन हर ऐप को WM_POWERBROADCAST संदेश के रूप में प्रसारित करता है।2 स्लीप और रिज़्यूम से जुड़े तीन मुख्य इवेंट हैं।
| इवेंट | अर्थ |
|---|---|
| PBT_APMSUSPEND | स्लीप में जाने वाला है (तैयारी का अंतिम अवसर) |
| PBT_APMRESUMEAUTOMATIC | रिज़्यूम हुआ (रिज़्यूम पर हमेशा आता है) |
| PBT_APMRESUMESUSPEND | उपयोगकर्ता क्रिया से हुआ रिज़्यूम (यह सशर्त है) |
PBT_APMSUSPEND स्लीप से ठीक पहले की सूचना है, और यहाँ फ़ाइलें बंद कर अवस्था सहेज कर तैयारी कर सकते हैं। दो शर्तें हैं, पर। पहली, प्रोसेसिंग के लिए दिया समय प्रति ऐप लगभग 2 सेकंड है, और यदि आप पार करें तो सिस्टम प्रतीक्षा किए बिना आगे बढ़ता है।1 दूसरी, गंभीर रूप से कम बैटरी जैसे आपात सस्पेंड पर बिना अग्रिम सूचना के तुरंत सो जाता है।2 “स्लीप से पहले पूरा करना ही होगा” वाला डिज़ाइन टिकता नहीं। सूचना को “यदि पहुँच गए तो कर लें” का अवसर मानें, और मुख्य काम रिज़्यूम पक्ष पर रखें।
रिज़्यूम पक्ष दो चरण हैं। सस्पेंड संक्रमण से रिज़्यूम पर PBT_APMRESUMEAUTOMATIC आता है। उसके ऊपर, यदि मशीन पावर बटन या कुंजी दबाने जैसी उपयोगकर्ता क्रिया से जागी (या बाद में उपयोगकर्ता उपस्थिति पता चली), तो PBT_APMRESUMESUSPEND आता है। इसके विपरीत, नेटवर्क पर रिमोट वेक या रखरखाव के लिए बिना-उपस्थिति वाला रिज़्यूम केवल PBT_APMRESUMEAUTOMATIC देता है।3 ये दो चरण स्वयं काम बाँटने का संकेत हैं — कनेक्शन दोबारा बनाने जैसी यांत्रिक पुनर्प्राप्ति PBT_APMRESUMEAUTOMATIC पर करें, और स्क्रीन अपडेट या पुनः-लॉगिन संकेत जैसे उपयोगकर्ता-मुखी काम PBT_APMRESUMESUSPEND पर।
sequenceDiagram
accTitle: स्लीप और रिज़्यूम की सूचना प्रवाह
accDescr: स्लीप से ठीक पहले लगभग 2 सेकंड की छूट के साथ PBT_APMSUSPEND आता है; रिज़्यूम पर PBT_APMRESUMEAUTOMATIC हमेशा आता है, और PBT_APMRESUMESUSPEND केवल उपयोगकर्ता-प्रेरित रिज़्यूम पर आता है
participant OS as OS
participant A as ऐप
OS->>A: PBT_APMSUSPEND(लगभग 2 सेकंड की छूट)
A->>A: अवस्था सहेजें और कनेक्शन बंद करें
Note over OS: स्लीप(कोड नहीं चलता)
OS->>A: PBT_APMRESUMEAUTOMATIC(रिज़्यूम पर आता है)
A->>A: पुनः-कनेक्ट और अवस्था पुनर्स्थापित करें
OS->>A: PBT_APMRESUMESUSPEND(केवल उपयोगकर्ता-प्रेरित)
A->>A: स्क्रीन अपडेट और अन्य उपयोगकर्ता-मुखी काम
चित्र 1: सूचनाएँ केवल “ठीक पहले एक शब्द, और रिज़्यूम के बाद एक या दो शब्द” हैं। पुनर्प्राप्ति का नायक रिज़्यूम पक्ष का काम है।
flowchart TB
accTitle: साधारण स्लीप और आपात सस्पेंड का अंतर
accDescr: साधारण स्लीप ठीक पहले लगभग 2 सेकंड की तैयारी के साथ PBT_APMSUSPEND देती है, पर गंभीर बैटरी जैसे आपात सस्पेंड बिना अग्रिम सूचना रुक जाता है, इसलिए अग्रिम सूचना पर निर्भर डिज़ाइन नहीं टिकता
n2["साधारण स्लीप"] --> pre["PBT_APMSUSPEND(लगभग 2 सेकंड छूट)"]
pre --> s1["तैयारी, फिर रुकना"]
e2["आपात सस्पेंड(गंभीर कम बैटरी)"] --> s2["बिना अग्रिम सूचना रुकना"]
s2 -.-> l2["सूचना आएगी मानने वाला डिज़ाइन नहीं टिकता"]
चित्र 2: आपात सस्पेंड बिना चेतावनी आता है। इसलिए तैयारी “यदि पहुँच गए तो बोनस” है, और मुख्य काम रिज़्यूम पक्ष पर जाता है।
ध्यान दें कि WM_POWERBROADCAST निम्न-पावर अवस्था के प्रकार (स्लीप बनाम हाइबरनेशन) में भेद नहीं करता।4 ऐप के लिए सही अमूर्तता इसे एक प्रकार का इवेंट मानना है: “रुका, और वापस आया”। बिना-विंडो सेवाएँ और कंसोल ऐप कॉलबैक रूप (DEVICE_NOTIFY_CALLBACK) में RegisterSuspendResumeNotification उपयोग कर वही सूचनाएँ पा सकते हैं।7
flowchart TB
accTitle: दो रिज़्यूम चरणों पर काम बाँटना
accDescr: रिज़्यूम पर आने वाले PBT_APMRESUMEAUTOMATIC पर पुनः-कनेक्ट जैसी यांत्रिक पुनर्प्राप्ति रखें; केवल उपयोगकर्ता-प्रेरित रिज़्यूम पर आने वाले PBT_APMRESUMESUSPEND पर स्क्रीन अपडेट या पुनः-लॉगिन संकेत जैसे उपयोगकर्ता-मुखी काम रखें
ra["PBT_APMRESUMEAUTOMATIC(रिज़्यूम पर)"] --> m["यांत्रिक पुनर्प्राप्ति"]
rs["PBT_APMRESUMESUSPEND(उपयोगकर्ता-प्रेरित)"] --> u["उपयोगकर्ता-मुखी काम"]
m -.-> m1["पुनः-कनेक्ट और हैंडल फिर खोलें"]
u -.-> u1["स्क्रीन अपडेट और पुनः-लॉगिन संकेत"]
चित्र 3: बिना-उपस्थिति रिज़्यूम पर बाद वाला नहीं आता, इसलिए आवश्यक पुनर्प्राप्ति बाद वाले पर रखने से छूट जाएगी।
3. Modern Standby — “स्लीप” का अर्थ बदल गया है
आधुनिक तथ्य जो समझना चाहिए वह Modern Standby है। पारंपरिक S3 स्लीप सरल मॉडल था जो “सिस्टम को समग्र रूप से रोकता था”; Modern Standby मशीन पर स्लीप स्मार्टफ़ोन जैसा मॉडल है जिसमें स्क्रीन बंद होने के बाद सिस्टम रुक-रुक कर चलता रहता है।
व्यावसायिक ऐप के लिए यहाँ महत्त्व यह है कि डेस्कटॉप ऐप स्लीप में प्रवेश के पहले चरण पर Desktop Activity Moderator (DAM) से रोके जाते हैं।6 सिस्टम स्वयं नेटवर्क चालू रखने और सूचनाएँ पाने के लिए समय-समय पर चलता रहता है, पर उससे लाभ पाने वाले घटक वे हैं जो इस तंत्र में भाग लेते हैं — साधारण डेस्कटॉप-ऐप कोड नहीं चलता। इसलिए डेवलपर की दृष्टि से निष्कर्ष Modern Standby और S3 दोनों के लिए एक है — इस धारणा पर डिज़ाइन करें कि स्लीप के दौरान आपका कोड नहीं चलता।
flowchart TB
accTitle: पारंपरिक स्लीप और Modern Standby का अंतर
accDescr: पारंपरिक S3 स्लीप पूरे सिस्टम को रोकता है, जबकि Modern Standby में स्क्रीन बंद होने के बाद सिस्टम रुक-रुक कर चलता है। दोनों में डेस्कटॉप ऐप DAM से रुके रहते हैं, इसलिए ऐप का कोड नहीं चलता
s3["पारंपरिक S3 स्लीप: पूरा सिस्टम रुकता है"] --> conc["ऐप का कोड नहीं चलता"]
ms["Modern Standby: सिस्टम रुक-रुक कर चलता है"] --> dam["डेस्कटॉप ऐप DAM से रुके रहते हैं"]
dam --> conc
चित्र 4: मॉडल बदल गया है, पर डेस्कटॉप ऐप के लिए निष्कर्ष एक है: “स्लीप के दौरान नहीं चल सकते”।
दूसरी सावधानी है सूचनाओं पर कितना भरोसा रखें। Modern Standby में निम्न-पावर आइडल में प्रवेश और निकास पारंपरिक सस्पेंड संक्रमण से मेल नहीं खाते, और बिना सूचना आए कनेक्शन पहले ही टूट सकता है। रिज़्यूम सूचना को सहायक मानें, और त्रुटि-पता से चालित पुनः-कनेक्शन (अध्याय 5) को मुख्य पुनर्प्राप्ति पथ पर रखें।
दूसरा अंतर व्यवहार का “फिसलन” एहसास है। स्लीप की गहराई तक पहुँचना चरणबद्ध है, और विच्छेद व रुकने का समय S3 जितना तीखा नहीं। “स्क्रीन अभी बंद हुई” और “सो गया” का भेद उपयोगकर्ता को भी दिखना कठिन है, इसलिए लक्षण लेते समय पुष्टि करें “क्या ढक्कन बंद किया” और “कितने मिनट आइडल छोड़ा”।
4. क्या टूटता है — क्लासिक लक्षण
TCP कनेक्शन मर चुका है। स्लीप के दौरान साथी पक्ष, NAT, और फ़ायरवॉल आपकी चुप्पी को टाइमआउट मानकर कनेक्शन त्याग देते हैं। बदतर, इस पक्ष का सॉकेट त्रुटि नहीं जानता, इसलिए वह केवल रिज़्यूम के बाद भेजने या पाने पर विफल होता है। या और बदतर, प्राप्त-प्रतीक्षा कभी त्रुटि देती ही नहीं (इसीलिए keepalive चाहिए)। डेटाबेस कनेक्शन और WebSocket का रूप वही है।
सीरियल-पोर्ट और USB-डिवाइस हैंडल अमान्य हो जाते हैं। USB-जुड़ा डिवाइस रिज़्यूम पर ऐसा लग सकता है मानो एक बार “निकाला और फिर लगाया” गया, और जो हैंडल खुला था वह त्रुटियाँ लौटाने लगता है। यही उपकरण-नियंत्रण ऐप का विशिष्ट पैटर्न है जो “केवल दोपहर के बाद संचार त्रुटि पाता है”। पुनः-कनेक्ट डिज़ाइन सीरियल-कम्युनिकेशन लेख में भी है।
समय की निरंतरता टूटती है। “हर 10 सेकंड पोल करें” जैसा टाइमर-चालित काम स्लीप के दौरान फायर नहीं होता। रिज़्यूम के तुरंत बाद कैसे फायर होता है (समाप्त देय काम एक बार तुरंत चलता है, अगली अवधि तक कुछ नहीं, आदि) आपके टाइमर API और रनटाइम से भिन्न होता है, इसलिए छूटे टिक का सँभाल निहित व्यवहार पर न छोड़ें — सुरक्षित तरीका है रिज़्यूम सूचना पर अनुसूची दोबारा बनाना। साथ ही, बीते-समय गणनाएँ (पिछले टाइमस्टैम्प से अंतर) अचानक “8 घंटे जितनी” हो जाती हैं, और औसत गणना या टाइमआउट निर्णय टूटते हैं। “हर रात 2 बजे चलाएँ” जैसा निर्धारित काम यदि उस समय PC सोया हो तो चलता ही नहीं (यदि चाहिए तो Task Scheduler की स्लीप-से-जगाने सुविधा से जगाएँ)।
flowchart TB
accTitle: समय की निरंतरता टूटने के तीन रूप
accDescr: आवधिक काम स्लीप में रुकता है और रिज़्यूम-बाद फायरिंग API से भिन्न है, इसलिए रिज़्यूम पर अनुसूची दोबारा बनाएँ; पिछले टाइमस्टैम्प से अंतर रिज़्यूम बाद विशाल हो जाता है, इसलिए गार्ड लगाएँ; निर्धारित काम सोए रहने पर नहीं चलता, इसलिए Task Scheduler की स्लीप-से-जाग पर विचार करें
t1["आवधिक काम: रुकता है"] -.-> g1["अनुसूची दोबारा बनाएँ"]
t2["बीता समय: फट जाता है"] -.-> g2["असामान्य अंतर गार्ड करें"]
t3["निर्धारित: चला ही नहीं"] -.-> g3["स्लीप-से-जाग"]
g1 ~~~ t2
g2 ~~~ t3
चित्र 5: टाइमर और समय का सँभाल इस धारणा पर लिखें कि “समय छलांग लगाता है”। तीन रूपों में से प्रत्येक का उपाय-प्रकार है।
flowchart TB
accTitle: स्लीप पार टूटने वाली तीन चीजें
accDescr: स्लीप पार, TCP कनेक्शन साथी पक्ष के टाइमआउट ने त्याग दिया होता है, USB डिवाइस का हैंडल पुनः-कनेक्ट के रूप में अमान्य होता है, और बीते-समय आधारित काम विशाल समय-छलांग देखता है। प्रत्येक को पुनः-कनेक्ट, पुनः-खोलना, और अंतर-गार्ड से पुनर्प्राप्त करें
sleep["स्लीप अंतराल"] --> tcp["TCP: साथी ने त्याग दिया"]
sleep --> more{"USB या बीता समय?"}
more --> usb["USB: हैंडल अमान्य"]
more --> time["बीता समय: छलांग"]
tcp -.-> r1["पता + पुनः-कनेक्ट"]
usb -.-> r2["डिवाइस पुनः खोलें"]
time -.-> r3["असामान्य अंतर गार्ड करें"]
चित्र 6: जो टूटता है तीन परिवारों में पड़ता है — “कनेक्शन”, “हैंडल”, और “समय की निरंतरता” — और प्रत्येक की पुनर्प्राप्ति का प्रकार तय है।
साझा संसाधनों पर पुनः-प्रमाणीकरण। नेटवर्क ड्राइव और VPN अक्सर रिज़्यूम के बाद फिर स्थापित करने पड़ते हैं, और रिज़्यूम के तुरंत बाद कुछ से कई दस सेकंड की “स्टार्टअप घाटी” होती है जिसमें पहुँच विफल होती है। रिज़्यूम के तुरंत बाद सब कुछ एक साथ पुनः-प्रयास न करना, थोड़ा प्रतीक्षा कर चरणों में पुनः-प्रयास करना अधिक सुरक्षित है।
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);
}
पुनः-कनेक्ट काम स्वयं इडेम्पोटेंट बनाएँ (जितनी बार बुलाएँ सुरक्षित), विफलता पर exponential backoff से पुनः-प्रयास करें, और स्थिर अवस्था में keepalive से मरा कनेक्शन जल्दी पकड़ें — ये तीन एक सेट के रूप में लें, तो न केवल स्लीप से रिज़्यूम, बल्कि संक्षिप्त नेटवर्क गिरावट या डिवाइस रीबूट भी बचेंगे।
flowchart TB
accTitle: रिज़्यूम-सह पुनः-कनेक्ट डिज़ाइन
accDescr: रिज़्यूम सूचना, संचार त्रुटि, और keepalive विफलता सभी एक ही इडेम्पोटेंट पुनः-कनेक्ट काम में आते हैं, जो विफलता पर exponential backoff से पुनः-प्रयास करता है
e1["रिज़्यूम सूचना(PBT_APMRESUMEAUTOMATIC)"] --> r["इडेम्पोटेंट पुनः-कनेक्ट काम"]
e2["संचार-त्रुटि पता"] --> r
e3["Keepalive विफलता"] --> r
r --> ok{"सफल?"}
ok -->|"हाँ"| run["सामान्य संचालन पर लौटें"]
ok -->|"नहीं"| back["exponential backoff बाद पुनः-प्रयास"]
back --> r
चित्र 7: पुनः-कनेक्ट को एक इडेम्पोटेंट पथ में केंद्रित करें, और उसी सड़क पर रिज़्यूम सूचना, त्रुटि-पता, या keepalive से प्रवेश करें।
समय के सँभाल पर फिर सोचें। “पिछली बार से बीता समय” उपयोग करने वाले काम पर ऐसा गार्ड लगाएँ जो असामान्य रूप से बड़े अंतर पर अंतराल अमान्य करे (औसत में न मिलाएँ, टाइमआउट न मानें)। रिज़्यूम पार बीता समय मापने के लिए स्लीप के दौरान आगे बढ़ने वाली घड़ी (wall-clock समय) और वास्तव में काम पर बिताए समय में भेद रखना पड़ता है।
जिन अंतरालों में स्लीप नहीं चाहिए, स्लीप स्पष्ट रूप से दबाएँ। डेटा माइग्रेशन, डिवाइस से सतत संचार आदि — जो काम सोया नहीं जा सकता — के दौरान SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) से सिस्टम जगा रख सकते हैं (स्क्रीन भी चालू रखनी हो तो ES_DISPLAY_REQUIRED जोड़ें)।45 अधिक शिष्ट विधि पावर-रिक्वेस्ट API (PowerCreateRequest + PowerSetRequest) है, जो कारण स्ट्रिंग जोड़ सकती है, और तब powercfg /requests दिखाएगा “कौन रोक रहा है और क्यों”।8 ध्यान दें कि SetThreadExecutionState से दमन प्रति थ्रेड है, और उसे उसी थ्रेड से साफ़ करें जिसने सेट किया। async/await जैसे काम जो थ्रेड बदलते हैं, हैंडल से प्रबंधित पावर-रिक्वेस्ट पक्ष उपयोग करें। सावधानियाँ हैं। पहली, ये जो दबाते हैं वह स्वचालित आइडल स्लीप है। ढक्कन बंद करना या Start मेनू से Sleep चुनना जैसी स्पष्ट उपयोगकर्ता क्रिया नहीं रोक सकते, इसलिए दमन चालू रहते भी इस अध्याय का पुनः-कनेक्ट डिज़ाइन नहीं छोड़ सकते। दूसरी, Modern Standby मशीन पर बैटरी पर, स्लीप टाइमआउट बीतने के कुछ समय बाद ये पावर रिक्वेस्ट भी काट दी जाती हैं। जो काम बाधित नहीं हो सकता उसे AC पावर या संचालन से गारंटी दें।8 तीसरी, काम खत्म होने पर हमेशा साफ़ करें। छूटा साफ़ नया बग बनता है: “यह PC, किसी कारण, सोता नहीं”।
flowchart TB
accTitle: स्लीप दबाने के दो साधन
accDescr: चाहे सुविधाजनक SetThreadExecutionState उपयोग करें या कारण स्ट्रिंग जोड़ सकने वाली और powercfg से प्रशासक को दिखने वाली पावर-रिक्वेस्ट API, काम खत्म होने पर हमेशा साफ़ करें
need["वह काम अंतराल जो सोया नहीं जा सकता"] --> a["SetThreadExecutionState"]
need --> b["पावर रिक्वेस्ट(PowerSetRequest)"]
a -.-> a1["सुविधाजनक — केवल फ़्लैग"]
b -.-> b1["कारण सहित — powercfg में दिखता है"]
a --> off["काम खत्म होने पर हमेशा साफ़ करें"]
b --> off
चित्र 8: किसी भी साधन के लिए, “खत्म होने पर साफ़ करें” परम शर्त है। कारण दिखा सकने वाली पावर रिक्वेस्ट संचालन के लिए दयालु है।
सेवाएँ और बिना-विंडो ऐप RegisterSuspendResumeNotification (DEVICE_NOTIFY_CALLBACK) से कॉलबैक सूचनाएँ पाते हैं।7 यदि सतत संचालन सच्ची आवश्यकता हो, मूल समाधान है सो जाने वाले क्लाइंट PC पर काम रेज़िडेंट रखने वाले डिज़ाइन पर फिर सोचना, और उसे सर्वर पक्ष या बिना-स्लीप संचालित मशीन पर ले जाना।
6. जाँच — powercfg और इवेंट लॉग
पावर के आसपास की जाँच OS के साथ आने वाले उपकरणों से अच्छी चलती है।
- सोता नहीं:
powercfg /requestsउन प्रोसेस और ड्राइवरों की सूची देता है जिन्होंने पावर रिक्वेस्ट जारी की। “ऐपSetThreadExecutionStateसाफ़ करना भूल गया” यहाँ भी दिखता है। - अपने आप जागता है:
powercfg /lastwakeसबसे हाल का जागने का कारण दिखाता है, औरpowercfg /waketimersअभी मशीन जगाने के लिए आरक्षित टाइमर दिखाता है। - Modern Standby गुणवत्ता:
powercfg /sleepstudyप्रति स्लीप अंतराल पावर खपत और गतिविधि की रिपोर्ट बनाता है।9 - टाइमलाइन पुष्टि: इवेंट लॉग (System) का Kernel-Power स्रोत स्लीप में प्रवेश और रिज़्यूम के रिकॉर्ड रखता है। उन्हें ऐप के लॉग से मिलाकर वस्तुनिष्ठ पुष्टि होती है कि “त्रुटि से ठीक पहले रिज़्यूम था”।
flowchart TB
accTitle: पावर-समस्या लक्षणों का जाँच कमांड से मेल
accDescr: सोता-नहीं लक्षण के लिए powercfg /requests से देखें कौन पावर रिक्वेस्ट पकड़े है; अपने-आप-जागता लक्षण के लिए /lastwake और /waketimers से जागने का कारण देखें; टाइमलाइन के लिए इवेंट लॉग का Kernel-Power
s1["सोता नहीं"] --> c1["powercfg /requests"]
s2["अपने आप जागता है"] --> c2["powercfg /lastwake और /waketimers"]
s3["टाइमलाइन पुष्टि करनी है"] --> c3["इवेंट लॉग का Kernel-Power"]
c1 -.-> note["भूला स्लीप-दमन भी दिखता है"]
चित्र 9: लक्षण जाँच कमांड से तीन परिवारों में मेल खाते हैं। पहले पुष्टि करें “क्या अभी सोया”, फिर बाँटें।
टिकट सँभालते समय, पहले यही पूछना कि “क्या PC ठीक पहले सोया था (क्या ढक्कन बंद किया)” अलगाव बहुत तेज़ करता है।
7. सारांश
- स्लीप अस्वीकार नहीं हो सकती। अग्रिम सूचना (PBT_APMSUSPEND) लगभग 2 सेकंड की छूट वाला best-effort है, और आपात में नहीं आती। मुख्य डिज़ाइन रिज़्यूम पक्ष पर रखें।
- रिज़्यूम सूचनाएँ PBT_APMRESUMEAUTOMATIC (सस्पेंड से रिज़्यूम पर) + PBT_APMRESUMESUSPEND (उपयोगकर्ता क्रिया पर) हैं। सूचना न आने की स्थिति के लिए त्रुटि-चालित पुनः-कनेक्ट मुख्य पथ पर रखें।
- मानें कि कनेक्शन और हैंडल रिज़्यूम पार नहीं बचते, और इडेम्पोटेंट पुनः-कनेक्ट + exponential backoff + keepalive का तीन-टुकड़ा सेट लागू करें।
- बीते-समय आधारित काम पर “असामान्य अंतर” का गार्ड लगाएँ। निर्धारित काम इस धारणा पर डिज़ाइन करें कि स्लीप के दौरान नहीं चलता।
- जो अंतराल सोया नहीं जा सकता,
SetThreadExecutionStateया पावर रिक्वेस्ट से स्लीप स्पष्ट दबाएँ, और खत्म होने पर हमेशा साफ़ करें। - जाँच
powercfg(/requests, /lastwake, /sleepstudy) और Kernel-Power इवेंट लॉग है। टिकट सँभालते समय पहले पूछें “क्या ठीक पहले सोया”।
ऐप की दृष्टि से स्लीप वह इवेंट है जिसमें “समय बिना चेतावनी छलांग लगाता है, आसपास के कनेक्शन कटते हैं, और फिर वापस आता है”। क्या आपने उसे असामान्य स्थिति के बजाय रोज़मर्रा के हिस्से के रूप में डिज़ाइन में बुना है — यही लैपटॉप युग में व्यावसायिक ऐप की स्थिरता बाँटता है।
संबंधित लेख
- सीरियल कम्युनिकेशन ऐप की गलतियाँ — पुनः-कनेक्शन और लॉग डिज़ाइन तक
- आपके ऐप की दृष्टि से Windows शटडाउन — निकास सूचनाएँ, रीस्टार्ट, और पावर हानि सही सँभालना
- Windows Efficiency Mode क्या है? — हरी पत्ती आइकन और उसे बंद करने का तरीका
- Windows पर Sleep(1) के बजाय Event Wait क्यों चुनें
- “Not Responding” वास्तव में क्या है — Windows ऐप के हैंग का निर्णय कैसे करता है, और न हैंग करने वाले ऐप कैसे डिज़ाइन करें
संबंधित परामर्श क्षेत्र
KomuraSoft LLC “स्लीप से रिज़्यूम के बाद संचार टूटता है” और “दोपहर के बाद डिवाइस से कनेक्शन गिरता है” जैसे बग की मूल-कारण जाँच, मौजूदा ऐप पर पुनः-कनेक्ट लॉजिक और पावर-इवेंट सँभाल जोड़ना, तथा लैपटॉप संचालन मानने वाले व्यावसायिक ऐप और उपकरण-नियंत्रण सॉफ़्टवेयर की डिज़ाइन समीक्षा सँभालता है।
संदर्भ लिंक
-
Microsoft Learn, PBT_APMSUSPEND event. यह इवेंट कंप्यूटर के सस्पेंड अवस्था में जाने से ठीक पहले आने पर; ऐप से डेटा सहेजने का आवश्यक काम पूरा करने की अपेक्षा पर; और सिस्टम के इस सूचना को सँभालने के लिए लगभग 2 सेकंड देने पर, जिसके बाद जारी ऐप व्यवधान के अधीन होता है। ↩ ↩2
-
Microsoft Learn, System Power Management Events. सिस्टम के स्लीप जैसे ऑपरेटिंग-मोड परिवर्तन अग्रिम प्रसारित करने पर; PBT_APMSUSPEND के आइडल स्लीप से पहले सूचित होने पर ताकि फ़ाइलें बंद कर डेटा सहेज सकें; आपात सस्पेंड (गंभीर बैटरी आदि) के अग्रिम सूचना न देने पर; इस संदेश के सँभाल को प्रति ऐप अधिकतम 2 सेकंड दिए जाने और टाइमआउट बाद काटे जाने पर; और रिज़्यूम पर हर ऐप के सूचित होने पर। ↩ ↩2 ↩3
-
Microsoft Learn, PBT_APMRESUMESUSPEND event. उपयोगकर्ता-प्रेरित रिज़्यूम या बाद में उपयोगकर्ता इनपुट पता चलने पर PBT_APMRESUMEAUTOMATIC के बाद भेजे जाने पर; रिमोट वेक जैसे बाहरी कारण से रिज़्यूम पर केवल PBT_APMRESUMEAUTOMATIC भेजे जाने पर; और ऐप से स्लीप समय बंद फ़ाइलें पुनः खोलने तथा उपयोगकर्ता इनपुट की तैयारी की अपेक्षा पर। ↩ ↩2
-
Microsoft Learn, WM_POWERBROADCAST message. रिज़्यूम पर PBT_APMRESUMEAUTOMATIC हमेशा भेजे जाने, और उपयोगकर्ता इनपुट से रिज़्यूम पर PBT_APMRESUMESUSPEND भी भेजे जाने पर; इस संदेश के निम्न-पावर अवस्था के प्रकार में भेद न करने पर; पावर-अवस्था संक्रमण के विवरण सिस्टम इवेंट लॉग में दर्ज होने पर; और सिस्टम को निम्न-पावर अवस्था में जाने से रोकने के लिए SetThreadExecutionState कॉल करने पर। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, SetThreadExecutionState function (winbase.h). ES_SYSTEM_REQUIRED और ES_DISPLAY_REQUIRED के सिस्टम की आइडल स्लीप और डिस्प्ले पावर-ऑफ दबा सकने पर; और ES_CONTINUOUS से सतत दमन घोषित कर काम खत्म होने पर अकेले ES_CONTINUOUS कॉल से साफ़ करने पर। ↩ ↩2
-
Microsoft Learn, Prepare software for modern standby. Desktop Activity Moderator (DAM) के Modern Standby संक्रमण के पहले चरण पर डेस्कटॉप ऐप रोकने पर; और सिस्टम के तब निम्न-पावर चरण और resiliency चरण में चरणबद्ध जाने पर, जिसमें केवल अनुमति प्राप्त घटक रुक-रुक कर चलते हैं। ↩ ↩2
-
Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). सस्पेंड/रिज़्यूम सूचना पाने के लिए पंजीकरण करने वाली API होने पर, और DEVICE_NOTIFY_CALLBACK निर्दिष्ट करने पर बिना-विंडो ऐप या सेवा विंडो हैंडल पर संदेश के अलावा कॉलबैक से सूचना पा सकने पर। ↩ ↩2
-
Microsoft Learn, PowerSetRequest function (winbase.h). PowerCreateRequest से बने पावर-रिक्वेस्ट ऑब्जेक्ट पर सिस्टम या डिस्प्ले जगा-रखने जैसा रिक्वेस्ट प्रकार सेट कर सकने पर; नैदानिक कारण स्ट्रिंग जोड़ सकने पर; और बकाया पावर रिक्वेस्ट powercfg /requests से गिन सकने पर। ↩ ↩2
-
Microsoft Learn, Modern standby SleepStudy. powercfg /sleepstudy से बनी रिपोर्ट से प्रति Modern Standby अंतराल पावर खपत, गतिविधि, और जागने का कारण (पावर बटन, उपयोगकर्ता इनपुट, वेक टाइमर, आदि) जाँच सकने पर। ↩
संबंधित लेख
निकटवर्ती विषयों में गहराई से जाने के लिए समान टैग वाले नवीनतम लेख।
DllMain और Loader Lock — DLL आरंभीकरण में "कुछ न करें" कहे जाने का वास्तविक कारण
DllMain से LoadLibrary क्यों न बुलाएँ या दूसरे थ्रेड से सिंक्रोनाइज़ न करें। प्राथमिक स्रोतों से यह लेख समझाता है कि लोडर लॉक हर DLL सूचन...
"Not Responding" वास्तव में क्या है — Windows ऐप के हैंग का निर्णय कैसे करता है, और न हैंग करने वाले ऐप कैसे डिज़ाइन करें
Windows का "Not Responding" वह तंत्र है जिसमें OS तय करता है कि विंडो ने 5 सेकंड संदेश नहीं लिया और उसे घोस्ट विंडो से बदल देता है। यह ले...
Win32 Thread Pool API — CreateThreadpoolWork से थ्रेड बनाए बिना समवर्तिता
क्या आपके नेटिव कोड में CreateThread कॉल बिखरी पड़ी हैं? यह लेख Vista में पुनर्डिज़ाइन की गई Win32 थ्रेड पूल API — work, timer, wait और i...
Named Pipes व्यवहार में — डिज़ाइन से सुरक्षा तक, Windows की मानक IPC
Named pipes — Windows की मानक इंटर-प्रोसेस कम्युनिकेशन — की व्यावहारिक मार्गदर्शिका। यह लेख प्राथमिक स्रोतों से बाइट और मैसेज मोड का चुना...
स्प्यूरियस वेकअप — Condition Variable "बिना सूचना के" क्यों जागती है और Windows पर सही प्रतीक्षा कैसे करें
कंडीशन वेरिएबल की प्रतीक्षा सूचना आए बिना भी लौट सकती है (स्प्यूरियस वेकअप)। यह लेख Windows इम्प्लीमेंटेशन से समझाता है कि विनिर्देश इसे ...
संबंधित विषय
ये पृष्ठ विषय को सेवाओं और निर्णयों के व्यापक संदर्भ में रखते हैं।
Windows के तकनीकी विषय
Windows विकास, बग जाँच और मौजूदा संपत्तियों के उपयोग का प्रवेश-द्वार।
इस विषय से जुड़ी सेवाएँ
यह लेख निम्नलिखित सेवाओं से सीधे जुड़ा है।
Windows ऐप विकास
व्यावसायिक ऐप, डिवाइस एकीकरण और संचार उपकरण, आवश्यकताओं से विकास तक।
अक्सर पूछे जाने वाले प्रश्न
इस लेख के विषय पर परामर्श में अक्सर पूछे जाने वाले प्रश्न।
- क्या ऐप स्लीप के बारे में पहले से जान सकता है और उसे अस्वीकार कर सकता है?
- वर्तमान Windows पर आप सूचना पा सकते हैं, पर अस्वीकार नहीं कर सकते। स्लीप से ठीक पहले WM_POWERBROADCAST संदेश PBT_APMSUSPEND इवेंट पहुँचाता है, और यहाँ फ़ाइलें बंद कर अवस्था सहेज कर तैयारी कर सकते हैं, पर प्रोसेसिंग के लिए दिया समय प्रति ऐप लगभग 2 सेकंड है, और यदि आप पार करें तो सिस्टम प्रतीक्षा किए बिना आगे बढ़ता है। गंभीर रूप से कम बैटरी जैसे आपात सस्पेंड पर अग्रिम सूचना स्वयं नहीं आती। इसलिए "स्लीप से पहले पूरा करना ही होगा" वाला डिज़ाइन टिकता नहीं; ऐसा डिज़ाइन चाहिए जो कट जब भी आए, रिज़्यूम पर वापस आ सके। जिस काम के दौरान आप सचमुच स्लीप नहीं चाहते, SetThreadExecutionState या पावर रिक्वेस्ट (PowerSetRequest) से स्लीप स्पष्ट रूप से दबाएँ।
- मशीन के रिज़्यूम होने का पता कैसे लगाऊँ?
- यदि ऐप के पास विंडो हो, तो WM_POWERBROADCAST सँभालें। सस्पेंड से रिज़्यूम पर PBT_APMRESUMEAUTOMATIC आता है, और यदि रिज़्यूम उपयोगकर्ता क्रिया (पावर बटन या कुंजी दबाना) से हुआ हो, तो उसके बाद PBT_APMRESUMESUSPEND आता है। बिना-उपस्थिति वाला रिज़्यूम जो तुरंत फिर सो जाता है केवल PBT_APMRESUMEAUTOMATIC देता है, इसलिए बुनियादी विभाजन यह है कि पुनः-कनेक्ट जैसे आवश्यक काम PBT_APMRESUMEAUTOMATIC पक्ष पर रखें और स्क्रीन अपडेट जैसे उपयोगकर्ता-मुखी काम PBT_APMRESUMESUSPEND पक्ष पर। बिना-विंडो सेवाएँ और कंसोल ऐप वही सूचनाएँ DEVICE_NOTIFY_CALLBACK के साथ RegisterSuspendResumeNotification से कॉलबैक द्वारा पा सकते हैं।
- क्या स्लीप के दौरान ऐप चलता रह सकता है?
- नियमतः नहीं। स्लीप के दौरान CPU निष्पादन स्वयं रुकता है (Modern Standby मशीन पर डेस्कटॉप ऐप Desktop Activity Moderator से रोके जाते हैं), और ऐप का कोड नहीं चलता। दो विकल्प हैं। एक है काम चलते समय ही स्लीप दबाना। SetThreadExecutionState पर ES_SYSTEM_REQUIRED निर्दिष्ट करना, या PowerCreateRequest/PowerSetRequest से पावर रिक्वेस्ट जारी करना, उस अंतराल के लिए स्वचालित आइडल स्लीप दबाता है (powercfg /requests से पुष्टि कर सकते हैं)। वह फिर भी ढक्कन बंद करने जैसी स्पष्ट स्लीप क्रिया नहीं रोक सकता, इसलिए दमन चालू रहते भी रिज़्यूम की तैयारी चाहिए। दूसरा है स्लीप स्वीकार कर "रिज़्यूम के बाद पकड़ना" डिज़ाइन करना। रात्रि बैच जैसे निर्धारित काम के लिए Task Scheduler के "इस कार्य को चलाने के लिए कंप्यूटर जगाएँ" से PC जगा भी सकते हैं। जो काम सचमुच लगातार चलना चाहिए वह सर्वर पर, या बिना-स्लीप कॉन्फ़िगर सेवा पर, रहता है।
- रिज़्यूम के बाद TCP कनेक्शन और सीरियल पोर्ट काम क्यों नहीं करते?
- क्योंकि नेटवर्क एडाप्टर और USB डिवाइस भी स्लीप के दौरान निम्न-पावर अवस्था में गिरते हैं। TCP कनेक्शन साथी पक्ष या NAT या फ़ायरवॉल टाइमआउट ने पहले ही त्याग दिया होता है, और रिज़्यूम के बाद भेजना/पाना त्रुटि लौटाता है (अक्सर त्रुटि आने तक पता नहीं चलता)। USB-से-सीरियल एडाप्टर आदि रिज़्यूम पर कभी डिवाइस निकालना और फिर लगाना माने जाते हैं, और जो हैंडल खुला था वह अमान्य हो जाता है। दोनों के लिए सही धारणा है कि "हैंडल और कनेक्शन रिज़्यूम पार नहीं बचते", और सही उत्तर है रिज़्यूम सूचना या संचार त्रुटि पर कनेक्शन दोबारा बनाने वाला पुनः-कनेक्ट लॉजिक लागू करना। आवधिक keepalive को विफलता पर exponential backoff वाले पुनः-प्रयास से जोड़ना स्थापित पैटर्न है।
- अप्रत्याशित स्लीप या अप्रत्याशित रिज़्यूम की जाँच कैसे करें?
- powercfg कमांड पहला उपकरण है। "सोता नहीं" दिशा में, powercfg /requests उन प्रोसेस और ड्राइवरों की सूची देता है जिन्होंने स्लीप रोकने वाली पावर रिक्वेस्ट जारी की है। "अपने आप जागता है" दिशा में, powercfg /lastwake सबसे हाल का जागने का कारण दिखाता है और powercfg /waketimers वे टाइमर दिखाता है जो अभी मशीन जगाने के लिए आरक्षित हैं। Modern Standby मशीन पर powercfg /sleepstudy स्लीप के दौरान खपत और गतिविधि की रिपोर्ट बनाता है। स्लीप और रिज़्यूम इतिहास इवेंट लॉग में भी दर्ज होता है (System लॉग का Kernel-Power स्रोत), इसलिए टाइमलाइन पर पुष्टि कर सकते हैं "कब सोया, और कब और क्यों जागा"।