私はCLR via C#
ジェフリー・リッチャーの本を読んでいたところです。彼のおかげで、そのトピックに関連する簡単な説明をすることもできます. (回答の詳細全体に完全に同意していないと仮定します)
まず第一に、TaskScheduler
オブジェクトはスケジュールされたタスクの実行を担当します。FCLには、スレッド プール タスク スケジューラと同期コンテキスト タスク スケジューラTaskScheduler
の 2 つの派生タイプが付属しています。デフォルトでは、すべてのアプリケーションがスレッド プール タスク スケジューラを使用します。このタスク スケジューラは、タスクをスレッド プールのワーカー スレッドにスケジュールします。の静的プロパティを照会することで、既定のタスク スケジューラへの参照を取得できます。TaskScheduler
Default
同期コンテキスト タスク スケジューラは、通常、グラフィカル ユーザー インターフェイスを備えたアプリケーションに使用されます。このタスク スケジューラは、すべてのタスクをアプリケーションの 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
_OrderedTaskScheduler
PrioritizingTaskScheduler
ThreadPerTaskScheduler