私はCLR via C#ジェフリー・リッチャーの本を読んでいたところです。彼のおかげで、そのトピックに関連する簡単な説明をすることもできます. (回答の詳細全体に完全に同意していないと仮定します)
まず第一に、TaskSchedulerオブジェクトはスケジュールされたタスクの実行を担当します。FCLには、スレッド プール タスク スケジューラと同期コンテキスト タスク スケジューラTaskSchedulerの 2 つの派生タイプが付属しています。デフォルトでは、すべてのアプリケーションがスレッド プール タスク スケジューラを使用します。このタスク スケジューラは、タスクをスレッド プールのワーカー スレッドにスケジュールします。の静的プロパティを照会することで、既定のタスク スケジューラへの参照を取得できます。TaskSchedulerDefault
同期コンテキスト タスク スケジューラは、通常、グラフィカル ユーザー インターフェイスを備えたアプリケーションに使用されます。このタスク スケジューラは、すべてのタスクをアプリケーションの GUI スレッドにスケジュールして、すべてのタスク コードがボタンやメニュー項目などの UI コンポーネントを正常に更新できるようにします。同期コンテキスト タスク スケジューラは、スレッド プールをまったく使用しません。TaskSchedulerの静的FromCurrentSynchronizationContextメソッドを照会することにより、同期コンテキスト タスク スケジューラへの参照を取得できます。
実装からわかるようSynchronizationContextTaskSchedulerに、内部的にSynchronizationContextフィールドを使用します。は、これらすべての問題を解決するFCLと呼ばれる基本クラスを定義します。System.Threading.SynchronizationContext
- GUI アプリケーションは、UI 要素を作成したスレッドがその UI 要素を更新できる唯一のスレッドであるというスレッド モデルを強制します。スレッド プール スレッドを介して UI 要素を更新しようとすると、コードが例外をスローするため、これは問題です。どういうわけか、スレッド プール スレッドは GUI スレッドに UI 要素を更新させる必要があります。
- ASP.NET アプリケーションでは、任意のスレッドが必要なことを実行できます。スレッド プール スレッドがクライアントの要求の処理を開始すると、クライアントのカルチャを想定できるため、Web サーバーはカルチャ固有の形式で数値、日付、および時刻を返すことができます。さらに、Web サーバーはクライアントの ID を引き受けることができるため、サーバーは、クライアントがアクセスを許可されているリソースにのみアクセスできます。スレッド プール スレッドが非同期操作を生成すると、非同期操作の結果を処理する別のスレッド プール スレッドによって完了される場合があります。この作業は元のクライアント要求に代わって実行されますが、カルチャと ID は新しいスレッド プール スレッドに「流れる」必要があるため、クライアントに代わって実行される追加の作業は、クライアントのカルチャと ID 情報を使用して実行されます。
簡単に言うと、派生SynchronizationContextオブジェクトはアプリケーション モデルをそのスレッド モデルに接続します。FCL は SynchronizationContext から派生したいくつかのクラスを定義しますが、通常、これらのクラスを直接扱うことはありません。実際、それらの多くは公開されておらず、文書化されていません。
SynchronizationContextほとんどの場合、アプリケーション開発者はクラスについて何も知る必要はありません。を実行awaitするTaskと、呼び出しスレッドのSynchronizationContext
オブジェクトが取得されます。スレッド プールのスレッドが を完了するTaskと、SynchronizationContext
オブジェクトが使用され、アプリケーション モデルに適切なスレッド モデルが確保されます。そのため、GUI スレッド
awaitsが の場合Task、オペレーターに続くコードawaitは GUI スレッドでも実行されることが保証され、そのコードが UI 要素を更新できるようになります。ASP.NET アプリケーションの場合、await 演算子に続くコードは、クライアントのカルチャとプリンシパル情報が関連付けられているスレッド プール スレッドで実行されることが保証されます。
TaskSchedulerもちろん、特別なタスク スケジューリングが必要な場合は、から派生した独自のクラスを定義できます。Microsoft は、タスクのサンプル コードを多数提供しており、Parallel Extensions Extras パッケージに多数のタスク スケジューラのソース コードを含めています。のようIOTaskSchedulerに、、、、、、。LimitedConcurrencyLevelTaskScheduler_OrderedTaskSchedulerPrioritizingTaskSchedulerThreadPerTaskScheduler