スレッド プールを使うためのベスト プラクティス

このトピックでは、スレッド プールを操作するためのベスト プラクティスについて説明します。

やるべきこと

  • スレッド プールを使用して、アプリで並列処理を行います。

  • 作業項目を使用して、UI スレッドをブロックせずに拡張タスクを実行します。

  • 有効期間が短く、独立した作業項目を作成します。 作業項目は非同期的に実行され、キューから任意の順序でプールに送信できます。

  • 更新を UI スレッドにディスパッチします。 WinUI 3 アプリでは、DispatcherQueue.TryEnqueueMicrosoft.UI.Dispatching.DispatcherQueueを使用します。

  • Sleep 関数の代わりに ThreadPoolTimer.CreateTimer を使用します。

  • 独自のスレッド管理システムを作成する代わりに、スレッド プールを使用します。 スレッド プールは、高度な機能を備えた OS レベルで実行され、プロセス内およびシステム全体のデバイス リソースとアクティビティに応じて動的にスケーリングするように最適化されています。

  • C++ では、作業項目デリゲートがアジャイル スレッド モデルを使用していることを確認します (C++ デリゲートは既定でアジャイルです)。

  • 使用時にリソース割り当てエラーが許容できない場合は、事前に割り当てられた作業項目を使用します。

してはいけないこと

  • 期間値が <1 ミリ秒 (0 を含む) の定期的なタイマーは作成しないでください。 これにより、作業項目はシングルショット タイマーとして動作します。

  • 期間パラメーターで指定した時間よりも完了するまでに時間がかかる定期的な作業項目は送信しないでください。

  • バックグラウンド タスクからディスパッチされた作業項目から UI の更新 (トーストや通知以外) を送信しないでください。 代わりに、バックグラウンド タスクの進行状況と完了ハンドラー ( IBackgroundTaskInstance.Progress など) を使用します。

  • async キーワードを使用する作業項目ハンドラーを使用する場合、作業項目に完全な状態が設定されているときにハンドラー内のすべてのコードが実行されたとは想定しないでください。 スレッド プールの作業項目は、ハンドラー内のすべてのコードが実行される前に完全な状態に設定できます。 ハンドラー内の await キーワードに続くコードは、作業項目が完全な状態に設定された後に実行される場合があります。

  • 事前に割り当てられた作業項目を再初期化せずに複数回実行しないでください。 定期的な作業項目を作成する