Aplikasi yang rusak saat bangun dari tidur — cara kerja event daya Windows dan cara membangun aplikasi bisnis yang bertahan

· · Windows, Manajemen daya, Pengembangan Windows, Aplikasi bisnis, Kontrol perangkat, Pemecahan masalah, Win32 API

“Saya menutup laptop, membukanya keesokan paginya, dan aplikasi bisnis penuh kesalahan.” “Aplikasi pemantauan peralatan hanya kehilangan data setelah makan siang.” “Alat residensial yang mengekspor ke Excel kadang berhenti pada kesalahan koneksi.” — Tiket-tiket ini berbagi satu tersangka. Tidur.

Aplikasi bisnis dari era ketika PC desktop menjadi arus utama ditulis dengan asumsi tak terucap bahwa “PC tetap menyala”. Medan utama hari ini adalah laptop, dan secara bawaan ia tidur setelah beberapa menit idle. Pada mesin yang mampu Modern Standby, semantik tidur itu sendiri telah berubah dari model tradisional. Ditujukan kepada pengembang yang menulis aplikasi bisnis dan perangkat lunak kontrol peralatan di Windows, artikel ini menata, dari sumber primer, apa yang OS beritahukan kepada aplikasi sebelum dan sesudah tidur, apa yang rusak, dan cara menulis aplikasi yang bertahan saat bangun.

1. Kesimpulan lebih dulu

  • Tidur adalah event yang aplikasi “tidak berhak menolak”. Anda diberi tahu tepat sebelumnya dengan WM_POWERBROADCAST (PBT_APMSUSPEND), tetapi masa tenggang sekitar 2 detik, dan pada suspend darurat notifikasi bahkan tidak datang.12
  • Saat bangun dari suspend, PBT_APMRESUMEAUTOMATIC datang, dan pada bangun yang dipicu pengguna PBT_APMRESUMESUSPEND datang juga. Pekerjaan wajib seperti menyambung ulang termasuk di yang pertama sebagai aturan. Transisi masuk dan keluar idle berdaya rendah Modern Standby tidak selalu selaras dengan notifikasi ini, jadi perlakukan notifikasi sebagai bantuan.34
  • Rancang dengan asumsi bahwa koneksi TCP, port serial, dan handle perangkat tidak bertahan melewati bangun. Logika sambung ulang yang membangunnya kembali pada notifikasi bangun atau kesalahan komunikasi adalah acara utamanya.
  • Waspadai timer dan penanganan waktu. Pekerjaan berkala berhenti selama tidur, dan cara ia menyala tepat setelah bangun berbeda menurut API timer dan runtime. “Lompatan besar pada waktu yang berlalu” juga terjadi, jadi pendekatan yang aman adalah membangun ulang jadwal saat bangun.
  • Tekan tidur secara eksplisit untuk interval yang tidak ingin Anda tiduri. Pakai SetThreadExecutionState (ES_SYSTEM_REQUIRED) atau power request (PowerSetRequest), dan selalu bersihkan saat pekerjaan selesai.45
  • Pada mesin Modern Standby sistem tetap berjalan sebentar-sebentar selama tidur, tetapi aplikasi desktop dijeda. Anda tidak dapat memegang harapan bahwa “aplikasi kita harus tetap berjalan selama tidur”.6
  • Alat investigasi standar adalah powercfg (/requests, /lastwake, /sleepstudy) dan Kernel-Power di event log.

2. Apa yang terjadi di sekitar tidur — alur event daya

OS menyiarkan perubahan keadaan daya ke setiap aplikasi sebagai pesan WM_POWERBROADCAST.2 Ada tiga event utama yang melibatkan tidur dan bangun.

Event Arti
PBT_APMSUSPEND Akan masuk tidur (kesempatan terakhir untuk bersiap)
PBT_APMRESUMEAUTOMATIC Bangun (selalu datang saat bangun)
PBT_APMRESUMESUSPEND Bangun yang disebabkan tindakan pengguna (yang ini bersyarat)

PBT_APMSUSPEND adalah notifikasi tepat sebelum tidur, dan di sini Anda dapat bersiap dengan menutup berkas dan menyimpan state. Ada dua syarat, walaupun. Pertama, waktu yang diizinkan untuk pemrosesan sekitar 2 detik per aplikasi, dan jika Anda melebihinya sistem lanjut tanpa menunggu.1 Kedua, pada suspend darurat seperti baterai kritis, ia tidur segera tanpa notifikasi di muka.2 Desain yang “harus selesai sebelum tidur” tidak bertahan. Perlakukan notifikasi sebagai kesempatan untuk “lakukan jika sempat”, dan taruh pekerjaan utama di sisi bangun.

Sisi bangun ada dua tahap. PBT_APMRESUMEAUTOMATIC datang saat bangun dari transisi suspend. Di atas itu, jika mesin bangun karena tindakan pengguna seperti tombol daya atau tekan tombol (atau kehadiran pengguna terdeteksi setelahnya), PBT_APMRESUMESUSPEND mengikuti. Sebaliknya, bangun tanpa pengawasan untuk remote wake lewat jaringan atau untuk pemeliharaan hanya mengirimkan PBT_APMRESUMEAUTOMATIC.3 Dua tahap ini sendiri adalah petunjuk cara membagi pekerjaan — lakukan pemulihan mekanis seperti membangun ulang koneksi pada PBT_APMRESUMEAUTOMATIC, dan lakukan tindakan yang menghadap pengguna seperti pembaruan layar atau prompt masuk ulang pada PBT_APMRESUMESUSPEND.

Alur notifikasi untuk tidur dan bangunPBT_APMSUSPEND datang tepat sebelum tidur dengan masa tenggang sekitar 2 detik; saat bangun, PBT_APMRESUMEAUTOMATIC selalu datang, dan PBT_APMRESUMESUSPEND mengikuti hanya untuk bangun yang dipicu penggunaAplikasiOSAplikasiOSTidur (kode tidak berjalan)PBT_APMSUSPEND (masa tenggang sekitar 2 detik)Simpan state dan tutup koneksiPBT_APMRESUMEAUTOMATIC (datang saat bangun)Sambung ulang dan pulihkan statePBT_APMRESUMESUSPEND (hanya bangun yang dipicu pengguna)Pembaruan layar dan pekerjaan lain yang menghadap pengguna

Gambar 1: Notifikasi hanyalah “satu kata tepat sebelumnya, dan satu atau dua kata setelah bangun”. Bintang pemulihan adalah pekerjaan di sisi bangun.

Perbedaan antara tidur biasa dan suspend daruratTidur biasa mengirimkan PBT_APMSUSPEND tepat sebelumnya dengan sekitar 2 detik untuk bersiap, tetapi suspend darurat seperti baterai kritis berhenti tanpa notifikasi di muka, jadi desain yang bergantung pada notifikasi di muka tidak bertahanTidur biasaPBT_APMSUSPEND (masa tenggang sekitar 2 detik)Bersiap, lalu berhentiSuspend darurat (baterai kritis)Berhenti tanpa notifikasi di mukaDesain yang mengasumsikan notifikasi akan datang tidak bertahan

Gambar 2: Suspend darurat datang tanpa peringatan. Jadi persiapan adalah “bonus jika sempat”, dan pekerjaan utama pergi ke sisi bangun.

Perhatikan bahwa WM_POWERBROADCAST tidak membedakan jenis keadaan berdaya rendah (tidur versus hibernasi).4 Abstraksi yang tepat bagi aplikasi adalah memperlakukannya sebagai satu jenis event: “ia berhenti, dan ia kembali”. Layanan tanpa jendela dan aplikasi konsol dapat menerima notifikasi yang sama dengan memakai RegisterSuspendResumeNotification dalam bentuk callback (DEVICE_NOTIFY_CALLBACK).7

Membagi pekerjaan di dua tahap bangunTaruh pemulihan mekanis seperti menyambung ulang pada PBT_APMRESUMEAUTOMATIC, yang datang saat bangun; taruh pekerjaan yang menghadap pengguna seperti pembaruan layar atau prompt masuk ulang pada PBT_APMRESUMESUSPEND, yang datang hanya pada bangun yang dipicu penggunaPBT_APMRESUMEAUTOMATIC (saat bangun)Pemulihan mekanisPBT_APMRESUMESUSPEND (bangun yang dipicu pengguna)Pekerjaan yang menghadap penggunaSambung ulang dan buka ulang handlePembaruan layar dan prompt masuk ulang

Gambar 3: Yang terakhir tidak datang pada bangun tanpa pengawasan, jadi menaruh pemulihan wajib di yang terakhir akan melewatkannya.

3. Modern Standby — arti “tidur” telah berubah

Fakta modern lain yang harus diserap adalah Modern Standby. Tidur S3 tradisional adalah model sederhana yang “menghentikan sistem secara keseluruhan”; tidur pada mesin Modern Standby adalah model mirip smartphone di mana sistem tetap berjalan sebentar-sebentar setelah layar mati.

Yang penting bagi aplikasi bisnis di sini adalah bahwa aplikasi desktop dijeda oleh Desktop Activity Moderator (DAM) pada tahap pertama masuk tidur.6 Sistem itu sendiri tetap berjalan dari waktu ke waktu untuk menjaga jaringan tetap hidup dan menerima notifikasi, tetapi komponen yang mendapat manfaat dari itu adalah yang berpartisipasi dalam mekanisme ini — kode aplikasi desktop biasa tidak berjalan. Jadi dari sudut pandang pengembang kesimpulannya sama untuk Modern Standby dan untuk S3 — rancang dengan asumsi bahwa kode Anda tidak berjalan selama tidur.

Perbedaan antara tidur tradisional dan Modern StandbyTidur S3 tradisional menghentikan sistem secara keseluruhan, sedangkan di bawah Modern Standby sistem tetap berjalan sebentar-sebentar setelah layar mati. Aplikasi desktop dijeda oleh DAM dalam kedua kasus, jadi kode aplikasi tidak berjalanTidur S3 tradisional: seluruh sistem berhentiKode aplikasi tidak berjalanModern Standby: sistem berjalan sebentar-sebentarAplikasi desktop dijeda oleh DAM

Gambar 4: Modelnya telah berubah, tetapi bagi aplikasi desktop kesimpulannya sama: “Anda tidak dapat berjalan selama tidur”.

Peringatan lain adalah betapa sedikitnya Anda dapat mengandalkan notifikasi. Di bawah Modern Standby, transisi masuk dan keluar idle berdaya rendah tidak selaras dengan transisi suspend tradisional, dan koneksi sudah dapat putus tanpa notifikasi pernah datang. Perlakukan notifikasi bangun sebagai bantuan, dan taruh penyambungan ulang yang dipicu deteksi kesalahan (Bab 5) pada jalur pemulihan utama.

Perbedaan lain adalah rasa “licin” dari perilakunya. Mencapai kedalaman tidur bertahap, dan waktu putus serta berhenti tidak setajam di bawah S3. Perbedaan antara “layar baru saja mati” dan “ia tidur” juga sulit dilihat pengguna, jadi ketika Anda menerima gejala Anda perlu mengonfirmasi “apakah mereka menutup lid” dan “berapa menit dibiarkan idle”.

4. Apa yang rusak — gejala klasik

Koneksi TCP sudah mati. Selama tidur, sisi lain, NAT, dan firewall memperlakukan keheningan Anda sebagai timeout dan membuang koneksi. Lebih buruk, soket di sisi ini tidak tahu tentang kesalahannya, jadi ia gagal hanya ketika Anda mengirim atau menerima setelah bangun. Atau lebih buruk lagi, tunggu terima tidak pernah error sama sekali (itulah mengapa Anda membutuhkan keepalive). Koneksi basis data dan WebSocket punya bentuk yang sama.

Handle port serial dan perangkat USB menjadi tidak valid. Perangkat yang terhubung USB dapat tampak, saat bangun, seolah “dicabut dan dipasang kembali” sekali, dan handle yang Anda buka mulai mengembalikan kesalahan. Itu pola khas aplikasi kontrol peralatan yang “mendapat kesalahan komunikasi hanya setelah makan siang”. Desain sambung ulang juga dibahas di artikel komunikasi serial.

Kontinuitas waktu putus. Pekerjaan yang didorong timer seperti “poll setiap 10 detik” tidak menyala selama tidur. Cara ia menyala tepat setelah bangun (pekerjaan yang sudah jatuh tempo menyala sekali segera, tidak terjadi apa-apa sampai periode berikutnya, dan sebagainya) berbeda menurut API timer dan runtime yang Anda pakai, jadi jangan menyerahkan penanganan tick yang terlewat kepada perilaku implisit — pendekatan yang aman adalah membangun ulang jadwal pada notifikasi bangun. Juga, perhitungan waktu yang berlalu (selisih dari stempel waktu sebelumnya) tiba-tiba menjadi “setara 8 jam”, dan perhitungan rata-rata atau penilaian timeout rusak. Pekerjaan terjadwal seperti “jalankan setiap malam pukul 02.00” sama sekali tidak berjalan jika PC tidur pada waktu itu (bangunkan dengan fitur bangun-dari-tidur Task Scheduler jika Anda membutuhkannya).

Tiga bentuk di mana kontinuitas waktu putusPekerjaan berkala berhenti selama tidur dan penyalaan pasca-bangun berbeda menurut API, jadi bangun ulang jadwal saat bangun; selisih dari stempel waktu sebelumnya menjadi besar setelah bangun, jadi jaga itu; pekerjaan terjadwal tidak berjalan jika mesin tidur, jadi pertimbangkan bangun-dari-tidur Task SchedulerPekerjaan berkala: berhentiBangun ulang jadwalWaktu yang berlalu: meledakJaga selisih abnormalTerjadwal: tidak pernah berjalanBangun-dari-tidur

Gambar 5: Tulis penanganan timer dan waktu dengan asumsi bahwa “waktu meloncat”. Masing-masing dari tiga bentuk punya jenis penanggulangan.

Tiga hal yang rusak melewati tidurMelewati tidur, koneksi TCP sudah dibuang oleh timeout di sisi lain, handle perangkat USB menjadi tidak valid sebagai sambung ulang, dan pekerjaan berbasis waktu yang berlalu mengamati lompatan waktu besar. Pulihkan masing-masing dengan sambung ulang, buka ulang, dan penjaga selisihInterval tidurTCP: rekan membuangnyaUSB atau waktu yang berlalu?USB: handle tidak validWaktu yang berlalu: lompatanDeteksi + sambung ulangBuka ulang perangkatJaga selisih abnormal

Gambar 6: Yang rusak jatuh ke tiga keluarga — “koneksi”, “handle”, dan “kontinuitas waktu” — dan masing-masing punya jenis pemulihan yang sudah mapan.

Autentikasi ulang ke sumber daya bersama. Drive jaringan dan VPN sering perlu dibangun ulang setelah bangun, dan ada “lembah start” beberapa hingga puluhan detik tepat setelah bangun di mana akses gagal. Lebih aman untuk tidak mencoba ulang semuanya sekaligus tepat setelah bangun, melainkan menunggu sebentar dan mencoba ulang secara bertahap.

5. Membangun aplikasi yang bertahan saat bangun

Prinsipnya satu hal. Asumsikan bahwa “koneksi dan handle tidak bertahan melewati tidur”, dan struktur aplikasi agar Anda selalu dapat pulih.

Deteksi bangun dan pulihkan. Ketika WM_POWERBROADCAST jendela tingkat atas menerima PBT_APMRESUMEAUTOMATIC, buang koneksi yang Anda pegang dan bangun ulang. Poinnya adalah tidak mengandalkan notifikasi bangun saja. Notifikasi yang terlewat dan komunikasi yang terjadi sebelum notifikasi keduanya nyata, jadi selalu pasangkan dengan jalur yang “menyambung ulang ketika kesalahan komunikasi terdeteksi”, dan perlakukan notifikasi bangun sebagai pemicu yang hanya memulai itu lebih awal.

// 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);
}

Buat pekerjaan sambung ulang itu sendiri idempotent (aman tidak peduli berapa kali dipanggil), coba ulang saat gagal dengan exponential backoff, dan dalam keadaan mantap deteksi koneksi mati lebih awal dengan keepalive — satukan ketiga itu sebagai satu set, dan Anda akan bertahan bukan hanya bangun dari tidur tetapi juga jatuh jaringan singkat atau reboot perangkat.

Desain sambung ulang yang tahan bangunNotifikasi bangun, kesalahan komunikasi, dan kegagalan keepalive semuanya masuk ke pekerjaan sambung ulang idempotent yang sama, yang mencoba ulang dengan exponential backoff saat gagalyatidakNotifikasi bangun (PBT_APMRESUMEAUTOMATIC)Pekerjaan sambung ulang idempotentDeteksi kesalahan komunikasiKegagalan keepaliveBerhasil?Kembali ke operasi normalCoba ulang setelah exponential backoff

Gambar 7: Konsentrasikan sambung ulang ke satu jalur idempotent, dan masuk jalan yang sama dari notifikasi bangun, deteksi kesalahan, atau keepalive.

Tinjau ulang penanganan waktu. Untuk pekerjaan yang memakai “waktu yang berlalu sejak terakhir”, pasang penjaga yang membatalkan interval ketika mendeteksi selisih yang abnormally besar (jangan lipat ke rata-rata, jangan perlakukan sebagai timeout). Mengukur waktu yang berlalu melewati bangun mensyaratkan menjaga perbedaan antara jam yang maju selama tidur (waktu dinding) dan waktu yang benar-benar dihabiskan untuk pekerjaan.

Tekan tidur secara eksplisit untuk interval yang tidak ingin Anda tiduri. Selama pekerjaan yang tidak boleh ditiduri — migrasi data, komunikasi berkelanjutan dengan perangkat, dan sebagainya — Anda dapat menjaga sistem tetap terjaga dengan SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) (tambahkan ES_DISPLAY_REQUIRED jika Anda juga ingin menjaga layar menyala).45 Metode yang lebih tertib adalah API power-request (PowerCreateRequest + PowerSetRequest), yang dapat menempelkan string alasan, dan powercfg /requests kemudian akan menunjukkan “siapa yang memblokirnya dan mengapa”.8 Perhatikan bahwa penekanan lewat SetThreadExecutionState adalah per thread, dan Anda membersihkannya dari thread yang sama yang menetapkannya. Untuk pekerjaan yang berganti thread, seperti async/await, pakai sisi power-request, yang dikelola oleh handle. Ada peringatannya. Pertama, yang ditekan ini adalah tidur idle otomatis. Mereka tidak dapat menghentikan tindakan pengguna eksplisit seperti menutup lid atau memilih Sleep dari menu Start, jadi Anda tidak dapat melewatkan desain sambung ulang bab ini bahkan saat penekanan aktif. Kedua, pada baterai pada mesin Modern Standby, power request ini juga dipotong beberapa waktu setelah timeout tidur berlalu. Pekerjaan yang tidak dapat diinterupsi harus dijamin oleh daya AC atau oleh operasi.8 Ketiga, selalu bersihkan saat pekerjaan selesai. Pembersihan yang terlewat menjadi bug baru: “PC ini, entah mengapa, tidak mau tidur”.

Dua sarana menekan tidurBaik Anda memakai SetThreadExecutionState yang nyaman atau API power-request yang dapat menempelkan string alasan dan terlihat oleh administrator lewat powercfg, selalu bersihkan saat pekerjaan berakhirInterval kerja yang tidak boleh ditiduriSetThreadExecutionStatePower request (PowerSetRequest)Nyaman — hanya flagDengan alasan — terlihat di powercfgSelalu bersihkan saat pekerjaan berakhir

Gambar 8: Untuk kedua sarana, “bersihkan saat selesai” adalah syarat mutlak. Power request yang dapat membuat alasan terlihat lebih ramah bagi operasi.

Layanan dan aplikasi tanpa jendela menerima notifikasi callback dengan RegisterSuspendResumeNotification (DEVICE_NOTIFY_CALLBACK).7 Jika operasi berkelanjutan adalah persyaratan sungguhan, solusi akarnya adalah meninjau ulang desain yang menahan pekerjaan residensial pada PC klien yang tidur, dan memindahkannya ke sisi server atau ke mesin yang dioperasikan tanpa tidur.

6. Investigasi — powercfg dan Event Log

Investigasi seputar daya dilayani dengan baik oleh alat yang ikut dengan OS.

  • Tidak mau tidur: powercfg /requests mencantumkan proses dan driver yang telah mengeluarkan power request. “Aplikasi lupa membersihkan SetThreadExecutionState” muncul di sini juga.
  • Bangun sendiri: powercfg /lastwake menunjukkan alasan bangun terbaru, dan powercfg /waketimers menunjukkan timer yang saat ini dicadangkan untuk membangunkan mesin.
  • Kualitas Modern Standby: powercfg /sleepstudy menghasilkan laporan konsumsi daya dan aktivitas per interval tidur.9
  • Mengonfirmasi linimasa: Sumber Kernel-Power di event log (System) menyimpan catatan masuk tidur dan bangun. Mencocokkannya dengan log aplikasi membiarkan Anda mengonfirmasi secara objektif apakah “ada bangun tepat sebelum kesalahan”.
Memetakan gejala masalah daya ke perintah investigasiUntuk gejala tidak-mau-tidur, temukan siapa yang memegang power request dengan powercfg /requests; untuk gejala bangun-sendiri, temukan alasan bangun dengan /lastwake dan /waketimers; untuk linimasa, pakai Kernel-Power di event logTidak mau tidurpowercfg /requestsBangun sendiripowercfg /lastwake dan /waketimersIngin mengonfirmasi linimasaKernel-Power di event logPenekanan tidur yang terlupa muncul juga

Gambar 9: Gejala memetakan ke perintah investigasi dalam tiga keluarga. Pertama konfirmasi “apakah baru saja tidur”, lalu belah.

Dalam penanganan tiket, hanya dengan bertanya lebih dulu “apakah PC tidur tepat sebelumnya (apakah mereka menutup lid)” sangat mempercepat isolasi.

7. Ringkasan

  • Tidur tidak dapat ditolak. Notifikasi di muka (PBT_APMSUSPEND) adalah best-effort dengan masa tenggang sekitar 2 detik, dan tidak datang dalam keadaan darurat. Taruh desain utama di sisi bangun.
  • Notifikasi bangun adalah PBT_APMRESUMEAUTOMATIC (saat bangun dari suspend) + PBT_APMRESUMESUSPEND (pada tindakan pengguna). Pertahankan sambung ulang yang didorong kesalahan pada jalur utama untuk kasus di mana notifikasi tidak datang.
  • Asumsikan bahwa koneksi dan handle tidak bertahan melewati bangun, dan implementasikan set tiga bagian berupa sambung ulang idempotent + exponential backoff + keepalive.
  • Pasang penjaga terhadap “selisih abnormal” pada pekerjaan berbasis waktu yang berlalu. Rancang pekerjaan terjadwal dengan asumsi bahwa ia tidak berjalan selama tidur.
  • Untuk interval yang tidak boleh ditiduri, tekan tidur secara eksplisit dengan SetThreadExecutionState atau power request, dan selalu bersihkan saat selesai.
  • Investigasi adalah powercfg (/requests, /lastwake, /sleepstudy) dan event log Kernel-Power. Dalam penanganan tiket, tanya lebih dulu “apakah ia tidur tepat sebelumnya”.

Dari sudut pandang aplikasi, tidur adalah event di mana “waktu meloncat tanpa peringatan, koneksi ke sekitar terputus, lalu ia kembali”. Apakah Anda telah merajut itu ke dalam desain sebagai bagian dari kehidupan sehari-hari, bukan sebagai situasi abnormal, adalah yang memisahkan kestabilan aplikasi bisnis di era laptop.

Artikel terkait

Area konsultasi terkait

KomuraSoft LLC menangani investigasi akar masalah bug seperti “komunikasi putus setelah bangun dari tidur” dan “koneksi ke perangkat jatuh setelah makan siang”, memasang ulang logika sambung ulang dan penanganan event daya pada aplikasi yang ada, serta tinjauan desain aplikasi bisnis dan perangkat lunak kontrol peralatan yang mengasumsikan operasi laptop.

Tautan referensi

  1. Microsoft Learn, PBT_APMSUSPEND event. Tentang ini adalah event yang datang tepat sebelum komputer masuk keadaan suspend; tentang aplikasi diharapkan menyelesaikan pekerjaan yang dibutuhkan untuk menyimpan data; dan tentang sistem yang mengizinkan sekitar 2 detik untuk menangani notifikasi ini, dengan aplikasi yang lanjut melewati itu dapat diinterupsi.  2

  2. Microsoft Learn, System Power Management Events. Tentang sistem yang menyiarkan perubahan mode operasi seperti tidur di muka; tentang PBT_APMSUSPEND yang diberitahukan sebelum tidur idle agar Anda dapat bersiap dengan menutup berkas dan menyimpan data; tentang suspend darurat (baterai kritis dan sejenisnya) yang tidak memberi notifikasi di muka; tentang penanganan pesan ini yang diizinkan maksimum 2 detik per aplikasi dan dipotong setelah timeout; dan tentang setiap aplikasi diberitahu saat bangun.  2 3

  3. Microsoft Learn, PBT_APMRESUMESUSPEND event. Tentang ini dikirim setelah PBT_APMRESUMEAUTOMATIC pada bangun yang dipicu pengguna atau ketika input pengguna terdeteksi setelahnya; tentang hanya PBT_APMRESUMEAUTOMATIC yang dikirim untuk bangun dari penyebab eksternal seperti remote wake; dan tentang aplikasi diharapkan membuka ulang berkas yang ditutup pada waktu tidur dan bersiap untuk input pengguna.  2

  4. Microsoft Learn, WM_POWERBROADCAST message. Tentang PBT_APMRESUMEAUTOMATIC selalu dikirim saat bangun, dengan PBT_APMRESUMESUSPEND dikirim juga pada bangun dari input pengguna; tentang pesan ini tidak membedakan jenis keadaan berdaya rendah; tentang rincian transisi keadaan daya yang dicatat di event log sistem; dan tentang memanggil SetThreadExecutionState untuk mencegah sistem masuk keadaan berdaya rendah.  2 3 4

  5. Microsoft Learn, SetThreadExecutionState function (winbase.h). Tentang ES_SYSTEM_REQUIRED dan ES_DISPLAY_REQUIRED yang dapat menekan tidur idle sistem dan mematikan tampilan; dan tentang menyatakan penekanan berkelanjutan dengan ES_CONTINUOUS dan membersihkannya dengan memanggil ES_CONTINUOUS saja saat Anda selesai.  2

  6. Microsoft Learn, Prepare software for modern standby. Tentang Desktop Activity Moderator (DAM) yang menjeda aplikasi desktop pada tahap pertama transisi ke Modern Standby; dan tentang sistem kemudian bergerak bertahap ke fase berdaya rendah dan fase resiliency, dengan hanya komponen yang diizinkan yang berjalan sebentar-sebentar.  2

  7. Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). Tentang ini adalah API yang mendaftar untuk menerima notifikasi suspend/resume, dan tentang menentukan DEVICE_NOTIFY_CALLBACK agar aplikasi atau layanan tanpa jendela dapat menerima notifikasi lewat callback selain pengiriman pesan ke handle jendela.  2

  8. Microsoft Learn, PowerSetRequest function (winbase.h). Tentang dapat menetapkan jenis permintaan seperti sistem atau tampilan tetap terjaga pada objek power-request yang dibuat dengan PowerCreateRequest; tentang dapat menempelkan string alasan diagnostik; dan tentang power request yang tertunda dapat dienumerasi dengan powercfg /requests.  2

  9. Microsoft Learn, Modern standby SleepStudy. Tentang laporan yang dihasilkan powercfg /sleepstudy membiarkan Anda memeriksa, per interval Modern Standby, konsumsi daya, aktivitas, dan alasan bangun (tombol daya, input pengguna, wake timer, dan sebagainya). 

Artikel terbaru dengan tag yang sama untuk mendalami topik-topik terdekat.

Halaman-halaman ini menempatkan topik dalam konteks layanan dan keputusan yang lebih luas.

Artikel ini berkaitan langsung dengan layanan berikut.

Pertanyaan yang sering diajukan

Pertanyaan yang sering muncul dalam konsultasi tentang topik artikel ini.

Bisakah aplikasi mengetahui tidur lebih dulu dan menolaknya?
Di Windows saat ini Anda dapat menerima notifikasi, tetapi tidak dapat menolak. Tepat sebelum tidur, pesan WM_POWERBROADCAST mengirimkan event PBT_APMSUSPEND, dan di sini Anda dapat bersiap dengan menutup berkas dan menyimpan state, tetapi waktu yang diizinkan untuk pemrosesan sekitar 2 detik per aplikasi, dan jika Anda melebihinya sistem lanjut tanpa menunggu. Pada suspend darurat seperti baterai kritis, notifikasi di muka itu sendiri tidak datang. Jadi desain yang "harus selesai sebelum tidur" tidak bertahan; Anda membutuhkan desain yang dapat pulih saat bangun tidak peduli kapan potongannya datang. Untuk rentang kerja yang benar-benar tidak ingin Anda tiduri, tekan tidur secara eksplisit dengan SetThreadExecutionState atau power request (PowerSetRequest).
Bagaimana cara mendeteksi bahwa mesin sudah bangun?
Jika aplikasi punya jendela, tangani WM_POWERBROADCAST. Saat bangun dari suspend, PBT_APMRESUMEAUTOMATIC datang, dan jika bangun disebabkan tindakan pengguna (tombol daya atau tekan tombol), PBT_APMRESUMESUSPEND mengikutinya. Bangun tanpa pengawasan yang segera tidur lagi hanya mengirimkan PBT_APMRESUMEAUTOMATIC, jadi pemisahan dasarnya adalah menaruh pekerjaan wajib seperti menyambung ulang di sisi PBT_APMRESUMEAUTOMATIC dan pekerjaan yang menghadap pengguna seperti pembaruan layar di sisi PBT_APMRESUMESUSPEND. Layanan tanpa jendela dan aplikasi konsol dapat menerima notifikasi yang sama lewat callback dengan memakai RegisterSuspendResumeNotification dengan DEVICE_NOTIFY_CALLBACK.
Bisakah saya menjaga aplikasi tetap berjalan selama tidur?
Sebagai aturan, tidak. Selama tidur, eksekusi CPU itu sendiri berhenti (pada mesin Modern Standby, aplikasi desktop dijeda oleh Desktop Activity Moderator), dan kode aplikasi tidak berjalan. Ada dua pilihan. Yang satu adalah menekan tidur hanya sementara pekerjaan berlangsung. Menentukan ES_SYSTEM_REQUIRED dengan SetThreadExecutionState, atau mengeluarkan power request dengan PowerCreateRequest/PowerSetRequest, akan menekan tidur idle otomatis untuk interval itu (Anda dapat mengonfirmasinya dengan powercfg /requests). Itu tetap tidak dapat menghentikan tindakan tidur eksplisit seperti pengguna menutup lid, jadi Anda tetap perlu siap untuk bangun bahkan saat penekanan aktif. Yang lain adalah menerima tidur dan merancang untuk "mengejar setelah bangun". Untuk pekerjaan terjadwal seperti batch malam, Anda juga dapat membangunkan PC dengan "Wake the computer to run this task" milik Task Scheduler. Pekerjaan yang benar-benar perlu berjalan terus-menerus termasuk di server atau layanan yang dikonfigurasi agar tidak tidur.
Mengapa koneksi TCP dan port serial berhenti bekerja setelah bangun?
Karena adapter jaringan dan perangkat USB juga turun ke keadaan berdaya rendah selama tidur. Koneksi TCP sudah dibuang oleh sisi lain atau oleh timeout NAT atau firewall, dan kirim/terima setelah bangun mengembalikan kesalahan (Anda sering tidak menyadarinya sampai ia error). Adapter USB-ke-serial dan sejenisnya kadang diperlakukan sebagai pencabutan dan pemasangan ulang perangkat saat bangun, dan handle yang Anda buka menjadi tidak valid. Untuk keduanya, asumsi yang benar adalah bahwa "handle dan koneksi tidak bertahan melewati bangun", dan jawabannya adalah mengimplementasikan logika sambung ulang yang membangun kembali koneksi pada notifikasi bangun atau kesalahan komunikasi. Menggabungkan keepalive berkala dengan coba ulang yang memakai exponential backoff saat gagal adalah pola yang sudah mapan.
Bagaimana cara menyelidiki tidur tak terduga atau bangun tak terduga?
Perintah powercfg adalah alat pertama. Di arah "tidak mau tidur", powercfg /requests mencantumkan proses dan driver mana yang telah mengeluarkan power request yang memblokir tidur. Di arah "bangun sendiri", powercfg /lastwake menunjukkan alasan bangun terbaru dan powercfg /waketimers menunjukkan timer yang saat ini dicadangkan untuk membangunkan mesin. Pada mesin Modern Standby, powercfg /sleepstudy menghasilkan laporan konsumsi dan aktivitas selama tidur. Riwayat tidur dan bangun juga dicatat di event log (sumber Kernel-Power di log System), jadi Anda dapat mengonfirmasi pada linimasa "kapan ia tidur, dan kapan serta mengapa ia bangun".

Profil penulis

Halaman perkenalan penulis artikel.

Go Komura

Direktur KomuraSoft LLC

Berspesialisasi dalam pengembangan perangkat lunak Windows, konsultasi teknis, dan investigasi bug, terutama pada proyek dengan sistem yang sudah ada dan bug yang sulit direproduksi.

Kembali ke blog