Aplikasi rusak setelah bangun dari tidur — mekanisme event daya dan cara merancang aplikasi bisnis yang tahan bangun
· Diperbarui pada: · Go Komura · Windows, Manajemen daya, Pengembangan Windows, Aplikasi bisnis, Kontrol perangkat, Pemecahan masalah, Win32 API
Riwayat revisi (1 pembaruan, terakhir pada 31 Aug 2026)
Catatan perubahan yang dilakukan pada artikel ini. Jika versi sebelumnya telah diarsipkan, versi itu tetap dapat dibaca melalui tautan permanen dengan DOI.
- Diterjemahkan ulang sebagai terjemahan lengkap dari naskah Jepang. Versi bahasa Indonesia sebelumnya adalah ringkasan yang hanya memindahkan sebagian naskah, sehingga bagian, tabel, gambar Mermaid, keterangan gambar, dan FAQ tidak ada. Semuanya dipulihkan sesuai naskah Jepang, dan klaim teknisnya sama dengan versi Jepang.
- Publikasi pertama
Mengutip artikel ini(DOI (arsip terdaftar): 10.5281/zenodo.22176741)
DOI di bawah mengarah ke versi yang telah diarsipkan sebelumnya dan mungkin berbeda dari teks saat ini. Gunakan URL halaman ini untuk merujuk teks saat ini.
Go Komura (2026). Aplikasi rusak setelah bangun dari tidur — mekanisme event daya dan cara merancang aplikasi bisnis yang tahan bangun. KomuraSoft LLC. https://comcomponent.com/id/blog/windows-sleep-resume-power-events/
- DOI (arsip terdaftar)
- 10.5281/zenodo.22176741
- DOI (versi terakhir yang didaftarkan)
- 10.5281/zenodo.22176742
“Laptop ditutup, keesokan paginya dibuka, aplikasi bisnis penuh error.” “Aplikasi pemantauan perangkat hanya kehilangan data setelah istirahat siang.” “Utilitas yang selalu berjalan dan mengekspor ke Excel kadang berhenti karena error koneksi.” — Laporan seperti ini punya satu tersangka yang sama. Tidur.
Aplikasi bisnis dari masa PC desktop masih arus utama ditulis dengan asumsi tersirat bahwa “PC tetap menyala”. Medan utama hari ini adalah laptop, dan secara bawaan, jika dibiarkan beberapa menit, sistem masuk tidur. Pada mesin yang mendukung Modern Standby, semantik tidur itu sendiri sudah berbeda dari model lama. Artikel ini ditujukan kepada pengembang yang membuat aplikasi bisnis dan perangkat lunak kontrol perangkat di Windows. Isinya menata, berdasarkan sumber primer, apa yang OS beritahukan kepada aplikasi sebelum dan sesudah tidur, apa yang rusak, dan bagaimana menulis aplikasi yang tahan bangun.
1. Kesimpulan lebih dulu
- Tidur adalah event yang aplikasi tidak punya hak menolak. Notifikasi datang tepat sebelumnya lewat
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; jika bangun karena tindakan pengguna, PBT_APMRESUMESUSPEND menyusul. Pekerjaan wajib seperti menyambung ulang pada dasarnya diletakkan di yang pertama. Masuk dan keluar idle berdaya rendah pada Modern Standby tidak selalu selaras dengan notifikasi ini, jadi notifikasi diperlakukan sebagai bantuan.34
- Rancang dengan asumsi bahwa koneksi TCP, port serial, dan handle perangkat tidak bertahan melewati bangun. Intinya adalah logika sambung ulang yang membangun kembali koneksi saat notifikasi bangun atau error komunikasi.
- Perhatikan timer dan penanganan waktu. Pemrosesan berkala berhenti selama tidur, dan cara timer terpicu tepat setelah bangun berbeda menurut API timer dan lingkungan eksekusi. “Lompatan besar pada waktu yang berlalu” juga terjadi, jadi yang aman adalah menyusun ulang jadwal saat bangun.
- Untuk rentang yang tidak ingin ditidurkan, tekan tidur secara eksplisit. Pakai
SetThreadExecutionState(ES_SYSTEM_REQUIRED) atau permintaan daya (PowerSetRequest), dan selalu lepas setelah pemrosesan selesai.45 - Pada mesin Modern Standby, sistem tetap bergerak sebentar-sebentar selama tidur, tetapi aplikasi desktop dijeda. Harapan bahwa “aplikasi kami tetap berjalan selama tidur” tidak bisa dipegang.6
- Investigasi yang sudah mapan memakai
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 semua aplikasi sebagai pesan WM_POWERBROADCAST.2 Event utama yang terkait tidur dan bangun ada tiga.
| Event | Arti |
|---|---|
| PBT_APMSUSPEND | Sebentar lagi masuk tidur (kesempatan terakhir untuk bersiap) |
| PBT_APMRESUMEAUTOMATIC | Sudah bangun (selalu datang saat bangun) |
| PBT_APMRESUMESUSPEND | Bangun karena tindakan pengguna (yang ini bersyarat) |
PBT_APMSUSPEND adalah notifikasi tepat sebelum tidur. Di sini berkas bisa ditutup dan state disimpan sebagai persiapan. Ada dua syarat. Pertama, waktu yang diizinkan untuk pemrosesan sekitar 2 detik per aplikasi; jika lewat, sistem lanjut tanpa menunggu.1 Kedua, pada suspend darurat seperti baterai kritis, sistem langsung tidur tanpa notifikasi di muka.2 Desain “harus selesai sebelum tidur” tidak valid. Perlakukan notifikasi sebagai kesempatan “kerjakan jika sempat”, dan taruh inti pekerjaan di sisi bangun.
Sisi bangun ada dua tahap. PBT_APMRESUMEAUTOMATIC datang saat bangun dari transisi suspend. Setelah itu, jika bangun karena tindakan pengguna seperti tombol daya atau input keyboard (atau kehadiran pengguna terdeteksi kemudian), PBT_APMRESUMESUSPEND menyusul. Sebaliknya, bangun tanpa pengawasan untuk remote wake lewat jaringan atau untuk pemeliharaan hanya mengirim PBT_APMRESUMEAUTOMATIC.3 Dua tahap ini sendiri adalah petunjuk pembagian kerja — pemulihan mekanis seperti membangun ulang koneksi dilakukan pada PBT_APMRESUMEAUTOMATIC, sedangkan tindakan yang menghadap pengguna seperti pembaruan layar atau permintaan login ulang dilakukan pada PBT_APMRESUMESUSPEND.
sequenceDiagram
accTitle: Alur notifikasi tidur dan bangun
accDescr: PBT_APMSUSPEND datang tepat sebelum tidur dengan masa tenggang sekitar 2 detik; saat bangun, PBT_APMRESUMEAUTOMATIC selalu datang, dan PBT_APMRESUMESUSPEND menyusul hanya jika bangun dipicu pengguna
participant OS as OS
participant A as Aplikasi
OS->>A: PBT_APMSUSPEND(masa tenggang sekitar 2 detik)
A->>A: Simpan state dan tutup koneksi
Note over OS: Tidur(kode tidak berjalan)
OS->>A: PBT_APMRESUMEAUTOMATIC(datang saat bangun)
A->>A: Sambung ulang dan pulihkan state
OS->>A: PBT_APMRESUMESUSPEND(hanya saat bangun dipicu pengguna)
A->>A: Pembaruan layar dan pemrosesan yang menghadap pengguna
Gambar 1: Notifikasi hanyalah “satu kata tepat sebelumnya, lalu satu atau dua kata setelah bangun”. Pemain utama pemulihan adalah pemrosesan di sisi bangun.
flowchart TB
accTitle: Perbedaan tidur biasa dan suspend darurat
accDescr: Tidur biasa mengirim 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 valid
n2["Tidur biasa"] --> pre["PBT_APMSUSPEND(masa tenggang sekitar 2 detik)"]
pre --> s1["Bersiap, lalu berhenti"]
e2["Suspend darurat(baterai hampir habis)"] --> s2["Berhenti tanpa notifikasi di muka"]
s2 -.-> l2["Desain yang mengasumsikan notifikasi akan datang tidak valid"]
Gambar 2: Suspend darurat datang tanpa peringatan. Karena itu persiapan adalah “untung jika sempat”, dan inti pekerjaan diletakkan di sisi bangun.
Perhatikan bahwa WM_POWERBROADCAST tidak membedakan jenis keadaan berdaya rendah (tidur atau hibernasi).4 Bagi aplikasi, abstraksi yang tepat adalah memperlakukannya sebagai satu jenis peristiwa: “berhenti, lalu kembali”. Pada layanan tanpa jendela dan aplikasi konsol, notifikasi yang sama bisa diterima dengan RegisterSuspendResumeNotification secara callback (DEVICE_NOTIFY_CALLBACK).7
flowchart TB
accTitle: Pembagian pemrosesan pada dua tahap bangun
accDescr: Pada PBT_APMRESUMEAUTOMATIC yang datang saat bangun diletakkan pemulihan mekanis seperti menyambung ulang; pada PBT_APMRESUMESUSPEND yang hanya datang saat tindakan pengguna diletakkan pemrosesan yang menghadap pengguna seperti pembaruan layar atau permintaan login ulang
ra["PBT_APMRESUMEAUTOMATIC(saat bangun)"] --> m["Pemulihan mekanis"]
rs["PBT_APMRESUMESUSPEND(saat bangun dipicu pengguna)"] --> u["Pemrosesan yang menghadap pengguna"]
m -.-> m1["Sambung ulang dan buka kembali handle"]
u -.-> u1["Pembaruan layar dan permintaan login ulang"]
Gambar 3: Pada bangun tanpa pengawasan, yang kedua tidak datang. Jika pemulihan wajib diletakkan di yang kedua, pekerjaan itu terlewat.
3. Modern Standby — arti “tidur” sudah berubah
Satu kondisi modern yang juga perlu dipegang adalah Modern Standby. Tidur S3 lama adalah model sederhana: “seluruh sistem berhenti”. Tidur pada mesin Modern Standby lebih dekat ke smartphone: setelah layar padam, sistem tetap bergerak sebentar-sebentar.
Yang penting bagi aplikasi bisnis di sini: aplikasi desktop dijeda oleh Desktop Activity Moderator (DAM) pada tahap pertama masuk tidur.6 Sistem sendiri sesekali bergerak untuk menjaga jaringan dan menerima notifikasi, tetapi yang mendapat manfaat itu adalah komponen yang mendukung mekanisme ini. Kode aplikasi desktop biasa tidak berjalan. Jadi dari sudut pandang pengembang, kesimpulan Modern Standby dan S3 sama — rancang dengan asumsi kode sendiri tidak berjalan selama tidur.
flowchart TB
accTitle: Perbedaan tidur lama dan Modern Standby
accDescr: Tidur S3 lama menghentikan seluruh sistem, sedangkan Modern Standby tetap menggerakkan sistem sebentar-sebentar setelah layar padam. Namun aplikasi desktop dijeda oleh DAM, sehingga pada keduanya kode aplikasi tidak berjalan
s3["Tidur S3 lama: seluruh sistem berhenti"] --> conc["Kode aplikasi tidak berjalan"]
ms["Modern Standby: sistem bergerak sebentar-sebentar"] --> dam["Aplikasi desktop dijeda oleh DAM"]
dam --> conc
Gambar 4: Modelnya berubah, tetapi kesimpulan bagi aplikasi desktop sama: “tidak bisa berjalan selama tidur”.
Perhatian lain adalah seberapa andal notifikasi. Pada Modern Standby, masuk dan keluar idle berdaya rendah tidak selaras dengan transisi suspend lama, sehingga koneksi bisa rusak tanpa notifikasi. Perlakukan notifikasi bangun sebagai bantuan, dan taruh sambung ulang dari deteksi error (bab 5) sebagai jalur utama pemulihan.
Perbedaan lain adalah “rasa bertahap”-nya. Masuk ke bagian dalam tidur terjadi secara bertingkat, sehingga waktu putus dan berhenti tidak sejelas S3. Perbedaan “hanya layar yang padam” versus “sudah tidur” juga sulit dirasakan pengguna. Karena itu, saat mendengar gejala, perlu dikonfirmasi apakah tutup laptop ditutup dan berapa menit PC dibiarkan.
4. Apa yang rusak — gejala yang sudah klasik
Koneksi TCP sudah mati. Selama tidur, lawan koneksi, NAT, dan firewall memperlakukan keheningan di sisi ini sebagai timeout dan membuang koneksi. Yang lebih buruk, soket di sisi ini belum tahu ada error, sehingga baru gagal saat kirim/terima setelah bangun. Atau lebih buruk lagi, menunggu terima tanpa pernah error (itulah sebabnya keepalive diperlukan). Koneksi database dan WebSocket punya pola yang sama.
Handle port serial dan perangkat USB menjadi tidak valid. Perangkat USB sering terlihat “dicabut lalu dipasang lagi” saat bangun, sehingga handle yang terbuka mulai mengembalikan error. Ini pola klasik aplikasi kontrol perangkat yang “hanya error komunikasi setelah istirahat siang”. Desain sambung ulang juga dibahas di artikel komunikasi serial.
Kontinuitas waktu rusak. Pemrosesan berbasis timer seperti “polling setiap 10 detik” tidak terpicu selama tidur. Cara terpicunya tepat setelah bangun (sisa yang kedaluwarsa langsung terpicu sekali, atau tidak terjadi apa-apa sampai periode berikutnya, dan sebagainya) berbeda menurut API timer dan lingkungan eksekusi. Karena itu, jangan serahkan penanganan yang terlewat pada perilaku implisit; yang aman adalah menyusun ulang jadwal pada notifikasi bangun. Selain itu, perhitungan berbasis waktu yang berlalu (selisih terhadap waktu sebelumnya) tiba-tiba menjadi “setara 8 jam”, sehingga rata-rata dan penentuan timeout rusak. Pemrosesan terjadwal seperti “jalan setiap malam pukul 02.00” sama sekali tidak dijalankan jika PC sedang tidur pada jam itu (jika perlu, bangunkan dengan fitur pelepasan tidur pada Penjadwal Tugas).
flowchart TB
accTitle: Tiga bentuk rusaknya kontinuitas waktu
accDescr: Pemrosesan berkala berhenti selama tidur dan cara terpicu setelah bangun berbeda per API sehingga jadwal disusun ulang saat bangun; selisih terhadap waktu sebelumnya menjadi nilai raksasa setelah bangun sehingga perlu dijaga; pemrosesan terjadwal tidak jalan jika mesin tidur sehingga pertimbangkan pelepasan tidur pada Penjadwal Tugas
t1["Pemrosesan berkala: berhenti selama tidur"] -.-> g1["Susun ulang jadwal saat bangun"]
t2["Selisih waktu yang berlalu: membesar"] -.-> g2["Jaga selisih yang tidak wajar"]
t3["Pemrosesan terjadwal: tidak jalan karena tidur"] -.-> g3["Bangunkan dengan pengaturan pelepasan tidur"]
Gambar 5: Tulis pemrosesan timer dan waktu dengan asumsi “waktu meloncat”. Masing-masing dari tiga bentuk punya pola penanganan.
flowchart TB
accTitle: Tiga hal yang rusak melewati tidur
accDescr: Melewati tidur, koneksi TCP dibuang oleh timeout di sisi lawan, handle perangkat USB menjadi tidak valid karena diperlakukan sebagai sambungan ulang, dan pemrosesan berbasis waktu yang berlalu mengamati lompatan waktu yang besar. Pulihkan masing-masing dengan sambung ulang, buka kembali, dan penjaga selisih
sleep["Interval tidur"] --> tcp["Koneksi TCP: sudah dibuang di sisi lawan"]
sleep --> usb["Perangkat USB: handle tidak valid"]
sleep --> time["Waktu yang berlalu: lompatan besar"]
tcp -.-> r1["Deteksi error dan sambung ulang"]
usb -.-> r2["Buka kembali perangkat"]
time -.-> r3["Jaga selisih yang tidak wajar"]
Gambar 6: Yang rusak ada tiga keluarga: “koneksi”, “handle”, dan “kontinuitas waktu”. Masing-masing punya pola pemulihan yang sudah tetap.
Otentikasi ulang ke sumber daya bersama. Network drive dan VPN sering perlu dibangun kembali setelah bangun, dan ada “lembah start-up” beberapa detik sampai puluhan detik tepat setelah bangun di mana akses gagal. Yang aman adalah tidak mencoba ulang semua sekaligus tepat setelah bangun, melainkan menunggu sebentar lalu mencoba ulang secara bertahap.
5. Cara merancang aplikasi yang tahan bangun
Prinsipnya satu. Asumsikan bahwa koneksi dan handle tidak bertahan melewati tidur, lalu buat struktur yang bisa dibangun kembali kapan saja.
Deteksi bangun, lalu pulihkan. Jika top-level window menerima PBT_APMRESUMEAUTOMATIC lewat WM_POWERBROADCAST, buang koneksi yang dipegang lalu sambung ulang. Poinnya: jangan mengandalkan notifikasi bangun saja. Notifikasi yang terlewat dan komunikasi sebelum notifikasi memang terjadi, jadi selalu sediakan jalur “jika error komunikasi terdeteksi, sambung ulang”. Notifikasi bangun diposisikan sebagai pemicu yang mempercepat jalur itu.
// C#: satukan notifikasi bangun dan error komunikasi ke pemrosesan sambung ulang yang sama
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(); // permintaan sambung ulang yang idempotent
}
base.WndProc(ref m);
}
Pemrosesan sambung ulang itu sendiri dibuat idempotent (aman dipanggil berkali-kali), mencoba ulang dengan exponential backoff saat gagal, dan pada operasi normal mendeteksi hidup-mati koneksi lebih awal lewat keepalive — tiga poin ini, jika dijadikan satu set, tidak hanya tahan bangun dari tidur, tetapi juga tahan putus jaringan sesaat dan restart perangkat.
flowchart TB
accTitle: Desain sambung ulang yang tahan bangun
accDescr: Notifikasi bangun, error komunikasi, dan kegagalan keepalive semuanya masuk ke pemrosesan sambung ulang yang sama dan idempotent, lalu mencoba ulang dengan exponential backoff saat gagal
e1["Notifikasi bangun(PBT_APMRESUMEAUTOMATIC)"] --> r["Pemrosesan sambung ulang yang idempotent"]
e2["Deteksi error komunikasi"] --> r
e3["Kegagalan keepalive"] --> r
r --> ok{"Berhasil?"}
ok -->|"ya"| run["Kembali ke operasi normal"]
ok -->|"tidak"| back["Coba ulang setelah exponential backoff"]
back --> r
Gambar 7: Kumpulkan sambung ulang menjadi satu pemrosesan idempotent, dan masuk ke jalur yang sama dari notifikasi bangun, deteksi error, maupun keepalive.
Tinjau ulang penanganan waktu. Pada pemrosesan yang memakai “waktu yang berlalu sejak sebelumnya”, pasang penjaga: jika selisih terdeteksi sangat besar, batalkan interval itu (jangan masukkan ke rata-rata, jangan perlakukan sebagai timeout). Untuk mengukur waktu yang berlalu melewati bangun, perlu membedakan waktu yang tetap maju selama tidur (waktu nyata) dari waktu yang dipakai untuk pemrosesan.
Untuk rentang yang tidak ingin ditidurkan, tekan tidur secara eksplisit. Selama pemrosesan yang bermasalah jika ditidurkan—migrasi data, komunikasi berkesinambungan dengan perangkat, dan sejenisnya—sistem bisa tetap terjaga dengan SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) (tambahkan ES_DISPLAY_REQUIRED jika layar juga ingin dipertahankan).45 Cara yang lebih tertib adalah API permintaan daya yang bisa menyertakan string alasan (PowerCreateRequest + PowerSetRequest); powercfg /requests lalu menampilkan “siapa menghalangi, dan mengapa”.8 Perhatikan bahwa penekanan SetThreadExecutionState berlaku per thread, dan pelepasan dilakukan dari thread yang sama dengan yang mengatur. Pada pemrosesan async/await yang pindah thread, pakai sisi permintaan daya yang dikelola lewat handle. Ada beberapa catatan. Pertama, yang ditekan adalah tidur otomatis karena tidak ada aktivitas. Tindakan eksplisit seperti menutup tutup laptop atau memilih tidur dari menu Start tidak bisa dicegah, jadi desain sambung ulang di bab ini tidak boleh dihilangkan meski penekanan aktif. Kedua, pada mesin Modern Standby yang memakai baterai, permintaan daya ini juga diputus beberapa waktu setelah timeout tidur berlalu. Pemrosesan yang tidak boleh terputus perlu dijamin dengan daya AC atau di sisi operasional.8 Ketiga, selalu lepas setelah pemrosesan selesai. Pelepasan yang terlewat menjadi bug baru: “PC ini entah mengapa tidak mau tidur.”
flowchart TB
accTitle: Dua cara menekan tidur
accDescr: Baik SetThreadExecutionState yang praktis maupun API permintaan daya yang bisa menyertakan string alasan dan terlihat oleh administrator lewat powercfg, selalu lepas saat pemrosesan selesai
need["Rentang pemrosesan yang tidak ingin ditidurkan"] --> a["SetThreadExecutionState"]
need --> b["Permintaan daya(PowerSetRequest)"]
a -.-> a1["Praktis, hanya flag"]
b -.-> b1["Ada alasan, terlihat di powercfg"]
a --> off["Selalu lepas saat pemrosesan selesai"]
b --> off
Gambar 8: Pada kedua cara, “lepas setelah selesai” adalah syarat mutlak. Permintaan daya yang bisa menampilkan alasan lebih ramah untuk operasional.
Layanan dan aplikasi tanpa jendela menerima notifikasi callback dengan RegisterSuspendResumeNotification (DEVICE_NOTIFY_CALLBACK).7 Jika selalu berjalan memang menjadi syarat, tinjau ulang desain yang menempatkan proses itu agar selalu berjalan di PC klien yang tidur, lalu pindahkan ke sisi server atau ke terminal yang dioperasikan tanpa tidur. Itu solusi mendasarnya.
6. Cara menelusuri — powercfg dan event log
Investigasi seputar daya sudah dilengkapi alat bawaan OS yang cukup baik.
- Tidak mau tidur:
powercfg /requestsmenampilkan proses dan driver yang mengeluarkan permintaan daya. “Aplikasi lupa melepasSetThreadExecutionState” juga ketemu di sini. - Bangun sendiri:
powercfg /lastwakemenunjukkan faktor bangun terakhir,powercfg /waketimersmenunjukkan timer yang sedang dijadwalkan untuk membangunkan. - Kualitas Modern Standby:
powercfg /sleepstudymenghasilkan laporan konsumsi daya dan aktivitas per interval tidur.9 - Konfirmasi linimasa: Sumber Kernel-Power pada event log (System) menyimpan catatan masuk tidur dan bangun. Dicocokkan dengan log aplikasi, bisa dikonfirmasi secara objektif apakah “ada bangun tepat sebelum error”.
flowchart TB
accTitle: Korespondensi gejala gangguan daya dan perintah investigasi
accDescr: Gejala tidak mau tidur ditelusuri dengan powercfg /requests untuk pemilik permintaan daya; gejala bangun sendiri ditelusuri dengan /lastwake dan /waketimers untuk faktor bangun; konfirmasi linimasa memakai Kernel-Power di event log
s1["Tidak mau tidur"] --> c1["powercfg /requests"]
s2["Bangun sendiri"] --> c2["powercfg /lastwake, /waketimers"]
s3["Ingin konfirmasi linimasa"] --> c3["Kernel-Power di event log"]
c1 -.-> note["Penekanan tidur yang lupa dilepas juga ketemu"]
Gambar 9: Gejala dan perintah investigasi terbagi tiga keluarga. Pastikan dulu “apakah baru saja tidur”, baru kemudian pilih alatnya.
Saat menangani laporan, hanya dengan bertanya lebih dulu “apakah PC tidur tepat sebelumnya (apakah tutup laptop ditutup)”, isolasi masalah menjadi jauh lebih cepat.
7. Ringkasan
- Tidur tidak bisa ditolak. Notifikasi di muka (PBT_APMSUSPEND) bersifat best-effort dengan masa tenggang sekitar 2 detik, dan tidak datang dalam keadaan darurat. Inti desain diletakkan di sisi bangun.
- Notifikasi bangun adalah PBT_APMRESUMEAUTOMATIC (saat bangun dari suspend) + PBT_APMRESUMESUSPEND (saat tindakan pengguna). Siapkan sambung ulang dari deteksi error sebagai jalur utama untuk kasus notifikasi tidak datang.
- Asumsikan koneksi dan handle tidak bertahan melewati bangun, lalu implementasikan set tiga bagian: sambung ulang idempotent + exponential backoff + keepalive.
- Pada pemrosesan berbasis waktu yang berlalu, pasang penjaga terhadap “selisih yang tidak wajar”. Rancang pemrosesan terjadwal dengan asumsi tidak berjalan selama tidur.
- Untuk rentang yang bermasalah jika ditidurkan, tekan tidur secara eksplisit dengan
SetThreadExecutionStateatau permintaan daya, dan selalu lepas setelah selesai. - Investigasi memakai
powercfg(/requests, /lastwake, /sleepstudy) dan event log Kernel-Power. Saat menangani laporan, tanya lebih dulu “apakah baru saja tidur”.
Dari sudut pandang aplikasi, tidur adalah event di mana “waktu meloncat tanpa peringatan, koneksi ke sekitar terputus, lalu sistem kembali”. Apakah hal itu sudah dijalin ke dalam desain sebagai bagian dari operasi sehari-hari, bukan sebagai keadaan abnormal, yang memisahkan kestabilan aplikasi bisnis di era laptop.
Artikel terkait
- Jebakan aplikasi komunikasi serial — sampai desain sambung ulang dan log
- Shutdown Windows dari sisi aplikasi — bertahan dengan benar dari notifikasi keluar, restart, dan putus daya
- Apa itu Windows Efficiency Mode — ikon daun hijau dan cara mematikannya
- Mengapa menunggu event lebih diutamakan daripada Sleep(1) di Windows
- Apa sebenarnya “Tidak Merespons” — cara Windows memutuskan aplikasi hang, dan cara merancang aplikasi yang tidak hang
Area konsultasi terkait
合同会社小村ソフト (KomuraSoft LLC) menangani investigasi penyebab gangguan seperti “komunikasi rusak setelah bangun dari tidur” dan “koneksi ke perangkat putus setelah istirahat siang”, implementasi susulan logika sambung ulang dan penanganan event daya pada aplikasi yang sudah ada, serta tinjauan desain aplikasi bisnis dan perangkat lunak kontrol perangkat yang mengasumsikan operasi laptop.
- Investigasi gangguan dan analisis penyebab
- Pengembangan aplikasi Windows
- Konsultasi teknis dan tinjauan desain
- Hubungi kami
Tautan referensi
-
Microsoft Learn, PBT_APMSUSPEND event. Tentang event yang datang tepat sebelum komputer masuk keadaan suspend; tentang aplikasi yang diharapkan menyelesaikan pemrosesan yang diperlukan untuk menyimpan data; serta tentang sistem yang mengizinkan sekitar 2 detik untuk menangani notifikasi ini, dan aplikasi yang terus memproses melewati itu bisa dihentikan. ↩ ↩2
-
Microsoft Learn, System Power Management Events. Tentang sistem yang menyiarkan di muka perubahan mode operasi seperti tidur; tentang PBT_APMSUSPEND yang diberitahukan sebelum tidur karena idle sehingga berkas bisa ditutup dan data disimpan sebagai persiapan; tentang suspend darurat (baterai kritis dan sejenisnya) yang tidak memberi notifikasi di muka; tentang penanganan pesan ini yang diizinkan paling lama 2 detik per aplikasi dan dipotong setelah timeout; serta tentang semua aplikasi diberitahu saat bangun. ↩ ↩2 ↩3
-
Microsoft Learn, PBT_APMRESUMESUSPEND event. Tentang pengiriman setelah PBT_APMRESUMEAUTOMATIC pada bangun karena tindakan pengguna atau saat input pengguna terdeteksi kemudian; tentang hanya PBT_APMRESUMEAUTOMATIC yang dikirim pada bangun dari faktor eksternal seperti remote wake; serta tentang aplikasi yang diharapkan membuka kembali berkas yang ditutup saat tidur dan bersiap menerima input pengguna. ↩ ↩2
-
Microsoft Learn, WM_POWERBROADCAST message. Tentang PBT_APMRESUMEAUTOMATIC yang selalu dikirim saat bangun, dan PBT_APMRESUMESUSPEND yang dikirim juga pada bangun dari input pengguna; tentang pesan ini yang tidak membedakan jenis keadaan berdaya rendah; tentang rincian transisi keadaan daya yang dicatat di event log sistem; serta tentang memanggil SetThreadExecutionState untuk mencegah sistem masuk keadaan berdaya rendah. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, SetThreadExecutionState function (winbase.h). Tentang ES_SYSTEM_REQUIRED dan ES_DISPLAY_REQUIRED yang bisa menekan tidur idle sistem dan mematikan layar; serta tentang menyatakan penekanan berkelanjutan dengan ES_CONTINUOUS, lalu melepasnya dengan memanggil ES_CONTINUOUS saja setelah selesai. ↩ ↩2
-
Microsoft Learn, Prepare software for modern standby. Tentang Desktop Activity Moderator (DAM) yang menjeda aplikasi desktop pada tahap pertama transisi ke Modern Standby; serta tentang sistem kemudian berpindah bertahap ke fase berdaya rendah dan fase resiliency, dengan hanya komponen yang diizinkan yang bergerak sebentar-sebentar. ↩ ↩2
-
Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). Tentang API untuk mendaftar penerimaan notifikasi suspend/resume; selain pengiriman pesan ke handle jendela, dengan menentukan DEVICE_NOTIFY_CALLBACK, aplikasi atau layanan tanpa jendela bisa menerima notifikasi lewat callback. ↩ ↩2
-
Microsoft Learn, PowerSetRequest function (winbase.h). Tentang bisa menetapkan jenis permintaan seperti menjaga sistem atau layar pada objek permintaan daya yang dibuat dengan PowerCreateRequest; tentang bisa menyertakan string alasan untuk diagnosis; serta tentang permintaan daya yang belum diselesaikan bisa dienumerasi dengan powercfg /requests. ↩ ↩2
-
Microsoft Learn, Modern standby SleepStudy. Tentang laporan yang dihasilkan powercfg /sleepstudy yang memungkinkan pemeriksaan konsumsi daya, aktivitas, dan faktor bangun (tombol daya, input pengguna, wake timer, dan sebagainya) per interval Modern Standby. ↩
Artikel terkait
Artikel terbaru dengan tag yang sama untuk mendalami topik-topik terdekat.
DllMain dan loader lock — alasan sebenarnya di balik peringatan "jangan lakukan apa pun saat inisialisasi DLL"
Mengapa LoadLibrary dan sinkronisasi antar-thread dilarang di dalam DllMain. Dari mekanisme loader lock yang menserialisasi semua notifik...
Apa sebenarnya "Tidak Merespons" — cara Windows menilai aplikasi hang, dan desain agar tidak hang
"Tidak Merespons" di Windows adalah mekanisme OS: jika jendela tidak mengambil pesan selama 5 detik, OS menilainya hang dan menggantinya ...
Membaca kode error Windows — struktur tiga lapis Win32, HRESULT, dan NTSTATUS
Jika 0x80004005 muncul, uraikan dulu sebelum mencari. Artikel ini membahas struktur tiga lapis Win32, HRESULT, dan NTSTATUS, pola terpent...
API thread pool Win32 — konkurensi tanpa membuat thread, lewat CreateThreadpoolWork
Apakah kode native masih menumpuk CreateThread? Artikel ini menjelaskan API thread pool Win32 yang didesain ulang di Vista: empat objek w...
Named pipe dalam praktik — IPC andalan Windows, dari desain sampai keamanan
Penjelasan praktis named pipe, IPC andalan di Windows. Dari sumber primer: memilih mode byte versus mode pesan, desain server yang menang...
Topik terkait
Halaman-halaman ini menempatkan topik dalam konteks layanan dan keputusan yang lebih luas.
Topik teknis Windows
Portal tentang pengembangan Windows, investigasi bug, dan pemanfaatan aset yang ada.
Layanan yang terkait dengan topik ini
Artikel ini berkaitan langsung dengan layanan berikut.
Pengembangan aplikasi Windows
Aplikasi bisnis, integrasi perangkat, dan alat komunikasi, dari kebutuhan hingga pengembangan.
Pertanyaan yang sering diajukan
Pertanyaan yang sering muncul dalam konsultasi tentang topik artikel ini.
- Bisakah aplikasi mengetahui lebih dulu bahwa sistem akan tidur, lalu menolaknya?
- Pada Windows saat ini, notifikasi bisa diterima, tetapi menolak tidak bisa. Tepat sebelum tidur, pesan WM_POWERBROADCAST membawa event PBT_APMSUSPEND. Di situ berkas bisa ditutup dan state disimpan sebagai persiapan, tetapi waktu yang diizinkan sekitar 2 detik per aplikasi. Jika lewat, sistem lanjut tanpa menunggu. Pada suspend darurat—misalnya baterai hampir habis—notifikasi di muka itu sendiri tidak datang. Karena itu, desain "harus selesai sebelum tidur" tidak valid. Yang dibutuhkan adalah desain yang bisa dibangun kembali saat bangun, kapan pun koneksi terputus. Untuk rentang pemrosesan yang memang tidak boleh ditidurkan, tekan tidur secara eksplisit dengan SetThreadExecutionState atau permintaan daya (PowerSetRequest).
- Bagaimana cara mendeteksi bahwa sistem sudah bangun?
- Aplikasi berjendela menangani WM_POWERBROADCAST. Saat bangun dari suspend, PBT_APMRESUMEAUTOMATIC datang. Jika bangun karena tindakan pengguna (tombol daya atau input keyboard), PBT_APMRESUMESUSPEND menyusul. Bangun tanpa pengawasan yang segera tidur lagi hanya mengirim PBT_APMRESUMEAUTOMATIC. Karena itu, pemisahan dasarnya: pekerjaan wajib seperti menyambung ulang diletakkan di PBT_APMRESUMEAUTOMATIC, sedangkan pekerjaan yang menghadap pengguna seperti pembaruan layar diletakkan di PBT_APMRESUMESUSPEND. Layanan tanpa jendela dan aplikasi konsol bisa menerima notifikasi yang sama lewat callback dengan RegisterSuspendResumeNotification dan flag DEVICE_NOTIFY_CALLBACK.
- Bisakah aplikasi tetap dijalankan selama tidur?
- Pada prinsipnya, tidak. Selama tidur, eksekusi CPU sendiri berhenti (pada mesin Modern Standby, aplikasi desktop dijeda oleh Desktop Activity Moderator), sehingga kode aplikasi tidak berjalan. Ada dua pilihan. Pertama, menekan tidur hanya selama pemrosesan berlangsung. Menentukan ES_SYSTEM_REQUIRED pada SetThreadExecutionState, atau mengeluarkan permintaan daya dengan PowerCreateRequest/PowerSetRequest, menekan tidur otomatis karena tidak ada aktivitas selama interval itu (bisa dicek dengan powercfg /requests). Namun tindakan tidur eksplisit seperti menutup tutup laptop tidak bisa dicegah, jadi persiapan untuk bangun tetap diperlukan meski penekanan aktif. Kedua, menerima tidur dan merancang agar "mengejar setelah bangun". Untuk pemrosesan terjadwal seperti batch malam, PC juga bisa dibangunkan dengan opsi Penjadwal Tugas yang membangunkan komputer saat menjalankan tugas. Pemrosesan yang benar-benar harus selalu berjalan lebih tepat dipindah ke server atau layanan yang dikonfigurasi agar tidak tidur.
- Mengapa koneksi TCP dan port serial tidak bisa dipakai setelah bangun?
- Karena adapter jaringan dan perangkat USB juga turun ke keadaan hemat daya selama tidur. Koneksi TCP sudah dibuang oleh sisi lawan atau oleh timeout NAT/firewall, sehingga kirim/terima setelah bangun menghasilkan error (sering baru ketahuan saat error terjadi). Konverter USB-serial dan sejenisnya kadang diperlakukan sebagai pencabutan lalu pemasangan ulang perangkat saat bangun, sehingga handle yang terbuka menjadi tidak valid. Untuk keduanya, asumsinya: handle dan koneksi tidak bertahan melewati bangun. Jawaban yang benar adalah mengimplementasikan logika sambung ulang yang membangun koneksi kembali saat notifikasi bangun atau error komunikasi. Menggabungkan keepalive berkala dengan percobaan ulang ber-exponential backoff saat gagal adalah pola yang sudah mapan.
- Bagaimana cara menelusuri penyebab tidur sendiri atau bangun sendiri?
- Perintah powercfg adalah alat pertama. Untuk arah "tidak mau tidur", powercfg /requests menampilkan proses dan driver mana yang mengeluarkan permintaan daya sehingga tidur terhalang. Untuk arah "bangun sendiri", powercfg /lastwake menunjukkan faktor bangun terakhir, dan powercfg /waketimers menunjukkan timer yang sedang dijadwalkan untuk membangunkan. Pada mesin Modern Standby, powercfg /sleepstudy menghasilkan laporan konsumsi dan aktivitas selama tidur. Riwayat tidur dan bangun juga tercatat di event log (sumber Kernel-Power pada log System), sehingga linimasa "kapan tidur, dan kapan serta karena apa bangun" bisa dikonfirmasi.
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.