Share via


中断/再開の最適化

プロセス継続時間システムの使用を合理化することで、中断または終了の後、効率的に再開されるユニバーサル Windows プラットフォーム (UWP) アプリを作成します。

起動

中断/終了の後、アプリを再アクティブ化するときは、長い時間が経過したかどうかを確認します。 そうである場合は、ユーザーの古いデータを表示する代わりに、アプリのメイン ランディング ページに戻ることを検討してください。 これにより、起動時間も短縮されます。

アクティブ化中は、常にイベント引数パラメーターの PreviousExecutionState を確認します (たとえば、起動済みのアクティブ化では、LaunchActivatedEventArgs.PreviousExecutionState を確認します)。 この値が ClosedByUser または NotRunning の場合は、以前に保存した状態を復元することで時間を無駄にしないでください。 この場合、正しいことは、新しいエクスペリエンスを提供することであり、結果として起動時間も短縮されます。

以前に保存した状態を頻繁に復元する代わりに、その状態を追跡して、必要な場合にのみ復元することを検討してください。 たとえば、以前にアプリが中断され、3 ページの状態が保存されてから、終了された場合を考えてみます。 再起動時に、ユーザーに対して 3 番目のページを表示する場合は、最初の 2 ページの状態を頻繁に復元しないでください。 代わりに、この状態を保持し、必要であることがわかった場合にのみ使用します。

実行中

ベスト プラクティスとして、中断イベントを待機し、大量の状態を保持することはしないでください。 代わりに、アプリケーションの実行中に少しずつ状態を保持するようにします。 これは、すべてを一度に保存しようとすると中断時に時間が不足するリスクがある大規模なアプリで特に重要です。

しかし、段階的な保存と実行中のアプリのパフォーマンスの最適なバランスを見つける必要があります。 適切な妥協点は、変更された (したがって、保存する必要がある) データを段階的に追跡し、中断イベントを使って実際にそのデータを保存することです (すべてのデータを保存したり、アプリ全体の状態を調べて保存する対象を決定したりするよりも高速です)。

ウィンドウの Activated や VisibilityChanged イベントを使って、状態を保存するタイミングを決定しないでください。 ユーザーがアプリを切り替えたときに、ウィンドウは非アクティブ化されますが、システムはアプリを中断するまでしばらくの間 (約 10 秒間) 待機します。 これは、ユーザーがすぐに元のアプリに戻った場合に、より応答性の高いエクスペリエンスを提供するためです。 中断ロジックを実行する前に、中断イベントを待機します。

Suspend

中断時に、アプリの占有領域を減らします。 中断中のアプリのメモリ使用量が少なくなると、システム全体の応答性が高くなり、(お客様のアプリを含む) 中断されたアプリが終了されることが少なくなります。 ただし、これと迅速な再開の必要性のバランスを取ってください。アプリで大量のデータをメモリに再読み込みしている間、再開が大幅に遅くなるほど占有領域を減らさないでください。

マネージド アプリの場合、システムによって、アプリの中断ハンドラーの完了後にガベージ コレクション パスが実行されます。 中断中のアプリの占有領域を減らすのに役立つオブジェクトへの参照を解放して、これを利用してください。

アプリでは中断ロジックを 1 秒未満で完了するのが理想的です。 中断は迅速に完了できるほどよく、他のアプリやシステムの部分の迅速なユーザー エクスペリエンスにつながります。 必要な場合は、デスクトップ デバイスで最大 5 秒間、モバイル デバイスでは 10 秒間、中断ロジックの処理に時間をかけることができます。 これらの時間を超過した場合、アプリは突然終了します。 これは望ましい結果ではありません。この場合、ユーザーがアプリに戻るときに、新しいプロセスが起動され、中断されたアプリを再開するときよりも、エクスペリエンスははるかに遅く感じられるためです。

[再開]

ほとんどのアプリでは、再開時に特別な処理を行う必要がないため、通常、このイベントは処理しません。 一部のアプリでは、再開を利用して、中断時に閉じられたた接続を復元したり、古くなっている可能性があるデータを更新したりします。 このような作業を頻繁に行う代わりに、必要に応じてこれらのアクティビティを開始するようアプリを設計します。 これにより、ユーザーが中断されたアプリに戻ったときのエクスペリエンスが迅速になり、ユーザーが実際に必要としている作業のみを確実に行えるようになります。

不必要な終了を回避する

UWP のプロセス継続時間システムでは、さまざまな理由でアプリを中断または終了することがあります。 このプロセスは、アプリを中断または終了する前の状態にすばやく戻すように設計されています。 うまく機能すると、アプリの実行が停止していたことにユーザーは気付きません。 ここでは、システムがアプリの有効期間内で切り替えを効率的に行うのに役立つように、UWP アプリで使用できるヒントをいくつか示します。

ユーザーがアプリをバックグラウンドに移動した場合、またはシステムが低電力状態になった場合にアプリを中断できます。 アプリが中断されると、suspending イベントが発生し、データを保存するのに最大 5 秒かかります。 アプリの suspending イベント ハンドラーが 5 秒以内に処理を完了できなかった場合、システムはアプリが応答を停止したと判断してアプリを終了します。 終了したアプリは、ユーザーがそのアプリに切り替えたときに、すぐにメモリに読み込まれることはなく、長い起動プロセスをもう一度実行する必要があります。

必要な場合にのみシリアル化する

多くのアプリでは、中断時にすべてのデータがシリアル化されます。 ただし、少量のアプリ設定データのみを格納する必要がある場合は、データをシリアル化するのではなく、LocalSettings ストアを使用する必要があります。 シリアル化は、もっと大量のデータや、設定以外のデータに使います。

データをシリアル化するときは、それが変更されていない場合は再シリアル化を避ける必要があります。 データのシリアル化と保存に時間がかかるばかりか、アプリが再びアクティブ化されたときにもデータの読み取りと逆シリアル化に時間がかかります。 代わりに、状態が実際に変更されたかどうかをアプリで判断し、そうである場合は、変更されたデータのみをシリアル化および逆シリアル化することをお勧めします。 これを確実に行うために、変更後にバックグラウンドでデータを定期的にシリアル化することをお勧めします。 この手法を使用すると、中断時にシリアル化する必要があるすべてが既に保存されているため、実行する作業がなく、アプリはすぐに中断されます。

C# と Visual Basic でのデータのシリアル化

.NET アプリに対して選べるシリアル化テクノロジは、System.Xml.Serialization.XmlSerializerSystem.Runtime.Serialization.DataContractSerializerSystem.Runtime.Serialization.Json.DataContractJsonSerializer クラスです。

パフォーマンスの観点から、XmlSerializer クラスを使うことをお勧めします。 XmlSerializer は、シリアル化と逆シリアル化の時間が最も短く、メモリ占有領域が低く維持されます。 XmlSerializer には、.NET Framework への依存関係はほとんどありません。つまり、他のシリアル化テクノロジと比較して、XmlSerializer を使用するためにアプリに読み込む必要があるモジュールが少なくなります。

XmlSerializer と比べて、DataContractSerializer は、カスタム クラスを比較的容易にシリアル化できる反面、パフォーマンスへの影響は大きくなります。 パフォーマンスを向上させる必要がある場合は、切り替えを検討してください。 一般に、複数のシリアライザーを読み込む必要はありません。また、別のシリアライザーの機能が必要な場合を除き、xmlSerializer を使用することをお勧めします。

メモリ占有領域を減らす

システムでは、中断されたアプリをできるだけ多くメモリに保持して、ユーザーがすばやく確実に切り替えられるようにしようとします。 アプリが中断され、システムのメモリ内に保持されている場合、スプラッシュ画面を表示したり、長時間の読み込み操作を実行したりすることなく、ユーザーが操作できるようにフォアグラウンドにすばやく移動できます。 アプリをメモリに保持するのに十分なリソースがない場合、アプリは終了します。 そのため、次の 2 つの理由でメモリ管理が重要になります。

  • 中断時にできるだけ多くのメモリを解放すると、中断中にリソースがないためにアプリが終了する可能性が最小限に抑えられます。
  • アプリで使用されるメモリの全体的な量を減らすと、中断中に他のアプリが終了する可能性が低くなります。

リソースを解放する

ファイルやデバイスなどの特定のオブジェクトは、大量のメモリを占有します。 中断中は、アプリでこれらのオブジェクトへのハンドルを解放し、必要に応じて再作成することをお勧めします。 これは、アプリの再開時に有効にならないキャッシュを消去する良い機会でもあります。 XAML フレームワークではユーザーの代わりに、必要に応じて、C# と Visual Basic アプリに対してガベージ コレクションを追加手順として実行します。 これによって、アプリ コードで参照されなくなったすべてのオブジェクトが解放されます。

すばやく再開する

中断されたアプリは、ユーザーがフォアグラウンドに移動したとき、またはシステムが低電力状態から復帰したときに再開できます。 アプリは中断状態から再開されると、中断された時点から続行されます。 アプリが長時間中断されていた場合でも、アプリのデータはメモリに格納されているため失われることはありません。

ほとんどのアプリでは、Resuming イベントを処理する必要はありません。 アプリ再開時の変数とオブジェクトは、アプリが中断されたときとまったく同じ状態です。 Resuming イベントは、アプリが中断されてから再開されるまでに変更された可能性のあるデータまたはオブジェクトを更新する必要がある場合にのみ処理します。たとえば、コンテンツ (更新フィード データなど)、古くなっている可能性があるネットワーク接続、デバイス (Web カメラなど) へのアクセスを再取得する必要がある場合などです。