スリープ復帰で壊れるアプリ ── 電源イベントの仕組みと復帰に強い業務アプリの作り方

· · Windows, 電源管理, Windows開発, 業務アプリ, 装置制御, 不具合調査, Win32 API

「ノートPCを閉じて、翌朝開いたら業務アプリがエラーだらけになっていた」「装置の監視アプリが、昼休みの後だけデータを取りこぼす」「Excelに出力する常駐ツールが、たまに接続エラーで止まっている」── これらの問い合わせには、共通するひとつの容疑者がいます。スリープです。

デスクトップPCが主流だった時代の業務アプリは、「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 スリープと復帰に関わる主要イベントは3つです。

イベント 意味
PBT_APMSUSPEND まもなくスリープに入る(最後の準備の機会)
PBT_APMRESUMEAUTOMATIC 復帰した(復帰時に必ず届く)
PBT_APMRESUMESUSPEND ユーザー操作による復帰(こちらは条件付き)

PBT_APMSUSPEND はスリープ直前の通知で、ここでファイルを閉じ、状態を保存する準備ができます。ただし条件が2つあります。第一に、処理に許される時間はアプリごとにおよそ2秒で、超えるとシステムは待たずに進みます。1 第二に、バッテリー残量が危機的な場合などの緊急サスペンドでは、この事前通知なしでいきなりスリープします2 「スリープ前に必ず完了させる」設計は成立しません。通知は「間に合えばやる」機会と捉え、本体は復帰側に置きます。

復帰側は2段階です。PBT_APMRESUMEAUTOMATIC はサスペンド遷移からの復帰時に届きます。そのうえで、電源ボタンやキー入力などユーザーの操作で復帰した(またはその後ユーザーの在席が検知された)場合には、続けて PBT_APMRESUMESUSPEND が届きます。逆に、ネットワーク経由の遠隔起動やメンテナンスのための無人復帰では PBT_APMRESUMEAUTOMATIC しか届きません。3 この2段階は使い分けのヒントそのものです ── 接続の張り直しなど機械的な立て直しは PBT_APMRESUMEAUTOMATIC で、画面の更新や再ログイン要求などユーザー向けの動作は PBT_APMRESUMESUSPEND で行います。

スリープと復帰の通知の流れスリープ直前にPBT_APMSUSPENDが約2秒の猶予付きで届き、復帰時はPBT_APMRESUMEAUTOMATICが必ず届いて、ユーザー操作による復帰の場合だけ続けてPBT_APMRESUMESUSPENDが届くアプリOSアプリOSスリープ(コードは動かない)PBT_APMSUSPEND(猶予約2秒)状態保存・接続クローズPBT_APMRESUMEAUTOMATIC(復帰時に届く)再接続・状態の立て直しPBT_APMRESUMESUSPEND(ユーザー復帰時のみ)画面更新などユーザー向け処理

図1: 通知は「直前に一言、復帰後に一言か二言」だけ。立て直しの主役は復帰側の処理になる。

通常スリープと緊急サスペンドの違い通常のスリープでは直前にPBT_APMSUSPENDが届き約2秒の準備時間があるが、クリティカルバッテリーなどによる緊急サスペンドでは事前通知なしで停止するため、事前通知に依存した設計は成立しない通常のスリープPBT_APMSUSPEND(約2秒の猶予)準備してから停止緊急サスペンド(電池切れ間際)事前通知なしで停止「通知が来る前提」の設計は不成立

図2: 緊急サスペンドは予告なし。だから準備は「できたら儲けもの」で、本体は復帰側に置く。

なお WM_POWERBROADCAST は低電力状態の種類(スリープか休止か)を区別しません。4 アプリにとっては「止まって、戻ってきた」という1種類の事象として扱うのが正しい抽象です。ウィンドウを持たないサービスやコンソールアプリでは、RegisterSuspendResumeNotification をコールバック方式(DEVICE_NOTIFY_CALLBACK)で使って同じ通知を受け取れます。7

復帰2段階の処理の使い分け復帰時に届く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・ファイアウォールはこちらの沈黙をタイムアウトとして処理し、接続を破棄します。悪いことに、こちら側のソケットはエラーを知らないままなので、復帰後に送受信して初めて失敗します。あるいはもっと悪く、受信待ちのままいつまでもエラーにならないこともあります(だからキープアライブが要るのです)。データベース接続やWebSocketも同じ構図です。

シリアルポート・USBデバイスのハンドルが無効になる。USB接続の機器は復帰時に一度「抜けて挿し直された」ように見えることがあり、開いていたハンドルはエラーを返すようになります。装置制御アプリで「昼休みの後だけ通信エラー」となる典型パターンです。再接続設計はシリアル通信の記事でも扱っています。

時間の連続性が壊れる。「10秒ごとにポーリング」のようなタイマー駆動処理は、スリープ中は発火しません。復帰直後にどう発火するか(期限切れ分が直ちに1回発火する、次の周期まで何も起きない等)は使っているタイマーAPIや実行環境によって異なるため、打ち逃した分の扱いを暗黙の挙動に任せず、復帰通知でスケジュールを組み直すのが安全です。また、経過時間ベースの計算(前回時刻との差分)が突然「8時間ぶん」になって、平均値の計算やタイムアウト判定が壊れる。「毎晩2時に実行」のような定時処理は、その時刻にPCが眠っていれば単に実行されません(必要ならタスクスケジューラのスリープ解除機能で起こします)。

時間の連続性が壊れる3つの形周期処理はスリープ中に止まり復帰後の発火はAPIごとに異なるため復帰時にスケジュールを組み直し、前回時刻との差分は復帰後に巨大な値になるためガードし、定時処理は眠っていると実行されないためタスクスケジューラのスリープ解除を検討する周期処理:スリープ中は止まる復帰時にスケジュールを組み直す経過時間の差分:巨大化異常な差分をガードする定時処理:眠っていて未実行スリープ解除の設定で起こす

図5: タイマーと時刻の処理は「時間が飛ぶ」前提で書く。3つの形それぞれに対処の型がある。

スリープをまたいで壊れる3つのものスリープをまたぐと、TCP接続は相手側のタイムアウトで破棄され、USB機器のハンドルは再接続扱いで無効になり、経過時間ベースの処理は巨大な時間ジャンプを観測する。それぞれ再接続・開き直し・差分ガードで立て直すスリープ区間TCP接続:相手側で破棄済みUSB機器:ハンドルが無効化経過時間:巨大なジャンプエラー検知と再接続デバイスを開き直す異常な差分をガード

図6: 壊れるものは「接続」「ハンドル」「時間の連続性」の3系統で、それぞれ立て直しの型が決まっている。

共有リソースへの再認証。ネットワークドライブやVPNは復帰後に再確立が必要なことがあり、復帰直後の数秒〜数十秒はアクセスが失敗する「立ち上がりの谷」が存在します。復帰直後に一斉リトライせず、少し待って段階的に再試行するのが安全です。

5. 復帰に強いアプリの作り方

原則はひとつです。「接続やハンドルはスリープをまたいで生き残らない」前提で、いつでも立て直せる構造にする。

復帰を検知して立て直す。トップレベルウィンドウの WM_POWERBROADCAST で PBT_APMRESUMEAUTOMATIC を受けたら、持っている接続を破棄して張り直します。ポイントは復帰通知だけに頼らないことです。通知の取りこぼしも通知前の通信も現実にあるので、「通信エラーを検知したら再接続する」経路を必ず併設し、復帰通知はそれを早めるトリガーと位置づけます。

// C#: 復帰通知と通信エラーの両方から同じ再接続処理に合流させる
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();   // 冪等な再接続要求
    }
    base.WndProc(ref m);
}

再接続処理そのものは、冪等(何度呼ばれても安全)に作り、失敗時は指数バックオフ付きで再試行し、定常時はキープアライブで接続の生死を早期検知する ── この3点セットにしておくと、スリープ復帰だけでなくネットワーク瞬断や機器の再起動にもそのまま耐えます。

復帰に強い再接続設計復帰通知と通信エラーとキープアライブ失敗のどれもが同じ冪等な再接続処理に合流し、失敗時は指数バックオフで再試行するはいいいえ復帰通知(PBT_APMRESUMEAUTOMATIC)冪等な再接続処理通信エラー検知キープアライブ失敗成功?通常運転へ指数バックオフ後に再試行

図7: 再接続を1本の冪等な処理に集約し、復帰通知・エラー検知・キープアライブのどこからでも同じ道に入る。

時間の扱いを見直す。「前回からの経過時間」を使う処理は、異常に大きな差分を検出したら区間を無効化する(平均に混ぜない、タイムアウト扱いにしない)ガードを入れます。復帰をまたいだ経過時間の計測には、スリープ中も進む時刻(実時間)と、処理に使った時間を区別する意識が必要です。

スリープさせたくない区間は明示的に抑止する。データ移行や装置との連続通信など、スリープされては困る処理の間は、SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) でシステムを起こしたままにできます(画面も維持したいなら ES_DISPLAY_REQUIRED を追加)。45 より行儀のよい方法が、理由の文字列を添えられる電源要求API(PowerCreateRequest + PowerSetRequest)で、powercfg /requests に「誰がなぜ妨げているか」が表示されます。8 なお SetThreadExecutionState の抑止はスレッド単位で、解除は設定と同じスレッドから行います。スレッドが替わるasync/await等の処理では、ハンドルで管理する電源要求側を使ってください。 注意点があります。第一に、これらが抑止するのは無操作による自動スリープです。ユーザーがフタを閉じる・スタートメニューからスリープを選ぶといった明示的な操作までは止められないため、抑止中であっても本章の再接続設計は省けません。第二に、Modern Standby機のバッテリー駆動では、これらの電源要求もスリープタイムアウト経過後しばらくすると打ち切られます。中断できない処理はAC電源や運用側で担保してください。8 第三に、処理が終わったら必ず解除すること。解除漏れは「このPC、なぜかスリープしなくなった」という新しい不具合になります。

スリープ抑止の2つの手段手軽に使えるSetThreadExecutionStateと、理由の文字列を添えられて管理者からpowercfgで見える電源要求APIのどちらを使う場合でも、処理の終了時に必ず解除するスリープされたくない処理区間SetThreadExecutionState電源要求(PowerSetRequest)手軽・フラグ指定のみ理由付き・powercfgで可視処理終了時に必ず解除

図8: どちらの手段でも「終わったら解除」が絶対条件。理由を可視化できる電源要求のほうが運用には親切。

サービス・ウィンドウレスアプリRegisterSuspendResumeNotification(DEVICE_NOTIFY_CALLBACK)でコールバック通知を受けます。7 常時稼働が本当に要件なら、そもそもスリープするクライアントPCに常駐させる設計を見直し、サーバー側かスリープしない運用の端末に寄せるのが根本解です。

6. 調べ方 ── powercfgとイベントログ

電源まわりの調査は、OS付属の道具立てがよくできています。

  • スリープしない: 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: 症状と調査コマンドの対応は3系統。まず「直前にスリープしたか」を確かめてから使い分ける。

問い合わせ対応では、まず「直前にPCはスリープしていましたか(フタを閉じたか)」と聞くだけで、切り分けが一気に速くなります。

7. まとめ

  • スリープは拒否できない。事前通知(PBT_APMSUSPEND)は約2秒の猶予付きベストエフォートで、緊急時には来ない。設計の本体は復帰側に置く。
  • 復帰通知は PBT_APMRESUMEAUTOMATIC(サスペンド復帰時)+ PBT_APMRESUMESUSPEND(ユーザー操作時)。通知が来ない場合に備えエラー検知の再接続を本線に。
  • 接続・ハンドルは復帰をまたいで生き残らない前提で、冪等な再接続+指数バックオフ+キープアライブの3点セットを実装する。
  • 経過時間ベースの処理には「異常な差分」へのガードを入れる。定時処理はスリープ中に走らないことを前提に設計する。
  • スリープされては困る区間は SetThreadExecutionState や電源要求で明示的に抑止し、終わったら必ず解除する。
  • 調査は powercfg(/requests・/lastwake・/sleepstudy)とKernel-Powerイベントログ。問い合わせ対応では「直前にスリープしたか」をまず聞く。

スリープは、アプリから見れば「予告なしに時間が飛び、周辺との接続が切れて戻ってくる」イベントです。これを異常事態ではなく日常の一部として設計に織り込めているかどうかが、ノートPC時代の業務アプリの安定性を分けます。

関連記事

関連する相談領域

合同会社小村ソフトでは、「スリープ復帰後に通信が壊れる」「装置との接続が昼休み後に切れる」といった不具合の原因調査、既存アプリへの再接続ロジック・電源イベント対応の後付け実装、ノートPC運用を前提とした業務アプリ・装置制御ソフトの設計レビューを扱っています。

参考リンク

  1. Microsoft Learn, PBT_APMSUSPEND event. コンピューターがサスペンド状態に入る直前に届くイベントであること、アプリはデータ保存に必要な処理を完了させるべきこと、システムがこの通知の処理に許すのはおよそ2秒であり、それを超えて処理を続けるアプリは中断されうることについて。  2

  2. Microsoft Learn, System Power Management Events. システムがスリープ等の動作モード変化を事前にブロードキャストすること、アイドルによるスリープ前にPBT_APMSUSPENDが通知されファイルクローズやデータ保存の準備ができること、緊急サスペンド(クリティカルバッテリーなど)では事前通知が行われないこと、このメッセージの処理にはアプリごとに最大2秒が許されタイムアウト後は打ち切られること、復帰時には全アプリに通知されることについて。  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. Modern Standbyへの移行の最初の段階でDesktop Activity Moderator(DAM)がデスクトップアプリを一時停止すること、その後システムが低電力フェーズ・レジリエンシーフェーズへ段階的に移行し、許可されたコンポーネントだけが間欠的に動作することについて。  2

  7. Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). サスペンド・レジューム通知の受信を登録するAPIで、ウィンドウハンドル宛のメッセージ配送に加え、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イベントが届き、ここでファイルを閉じる・状態を保存するなどの準備ができますが、処理に許される時間はアプリごとにおよそ2秒で、超えるとシステムはアプリを待たずに進みます。またバッテリー切れ間際などの緊急サスペンドでは事前通知そのものが来ません。したがって「スリープ前に必ず完了させる」設計は成立せず、「いつ切られても復帰時に立て直せる」設計にする必要があります。どうしてもスリープさせたくない処理区間は、SetThreadExecutionStateや電源要求(PowerSetRequest)で明示的に抑止します。
復帰したことはどうやって検知すればよいですか?
ウィンドウを持つアプリならWM_POWERBROADCASTを処理します。サスペンドからの復帰時にはPBT_APMRESUMEAUTOMATICが届き、ユーザーの操作(電源ボタンやキー入力)による復帰の場合はその後にPBT_APMRESUMESUSPENDも届きます。無人で復帰してすぐ再スリープする場合はPBT_APMRESUMEAUTOMATICしか来ないため、再接続などの必須処理はPBT_APMRESUMEAUTOMATIC側に置き、画面更新などユーザー向けの処理をPBT_APMRESUMESUSPEND側に置く使い分けが基本です。ウィンドウを持たないサービスやコンソールアプリは、RegisterSuspendResumeNotificationをDEVICE_NOTIFY_CALLBACK指定で使えばコールバックで同じ通知を受け取れます。
スリープ中もアプリを動かし続けることはできますか?
原則としてできません。スリープ中はCPUの実行自体が止まり(Modern Standby機ではデスクトップアプリはDesktop Activity Moderatorにより一時停止され)、アプリのコードは走りません。選択肢は2つです。ひとつは、処理中だけスリープを抑止すること。SetThreadExecutionStateにES_SYSTEM_REQUIREDを指定するか、PowerCreateRequest/PowerSetRequestで電源要求を出せば、無操作による自動スリープをその間抑止できます(powercfg /requestsで確認できます)。ただしユーザーがフタを閉じるなどの明示的なスリープ操作までは止められないため、抑止中でも復帰への備えは必要です。もうひとつは、スリープを受け入れて「復帰後に追いつく」設計にすることです。夜間バッチのような定時処理は、タスクスケジューラの「タスクの実行時にスリープを解除する」でPCを起こす方法もあります。常時稼働が本当に必要な処理は、スリープしない設定のサーバーやサービスに寄せるのが正道です。
復帰後にTCP接続やシリアルポートが使えなくなるのはなぜですか?
スリープ中はネットワークアダプターやUSBデバイスも省電力状態に落ちるためです。TCP接続は相手側やNAT・ファイアウォールのタイムアウトで破棄されており、復帰後の送受信はエラーになります(エラーになるまで気づけないことも多い)。USBシリアル変換器などは復帰時にデバイスの取り外し・再接続として扱われることがあり、開いていたハンドルは無効になります。どちらも「ハンドルや接続は復帰をまたいで生き残らない」前提で、復帰通知や通信エラーを契機に接続を張り直す再接続ロジックを実装するのが正解です。定期的なキープアライブと、失敗時の指数バックオフ付き再試行を組み合わせるのが定石です。
勝手にスリープする・勝手に復帰する原因はどう調べますか?
powercfgコマンドが第一の道具です。「スリープしない」方向ではpowercfg /requestsで、どのプロセス・ドライバーが電源要求を出してスリープを妨げているかが一覧できます。「勝手に起きる」方向ではpowercfg /lastwakeで直前の復帰要因が、powercfg /waketimersで復帰予約中のタイマーが確認できます。Modern Standby機ではpowercfg /sleepstudyでスリープ中の消費とアクティビティのレポートが出ます。また、スリープ・復帰の履歴はイベントログ(システムログのKernel-Powerソース)に記録されるため、「いつスリープし、いつ何が理由で起きたか」を時系列で確認できます。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る