タスクコンセプトとTPLの全体をまだ学習しています。私の現在の理解から、SynchronizationContext関数(存在する場合)はawait
によってタスクの「どこかに」ディスパッチするために使用されます。一方、Task
クラスの関数はコンテキストを使用しませんよね?
したがって、たとえばTask.Run(...)
は常にスレッドプールのワーカースレッドでアクションをディスパッチし、_SynchronizationContext.Current
_を完全に無視します。 await Foobar()
は、コンテキストを使用してawait
の後に生成されたタスクを実行しますか?
それが本当である場合、私の質問は次のとおりです。実際にアクションを実行するが、_SynchronizationContext.Current.Send/Post
_を使用してディスパッチされるTask
を取得するにはどうすればよいですか?
そして、誰かがSynchronizationContext
への優れた導入を推奨できますか?特に、フレームワークの残りの部分でそれらがいつどのように使用されるのか? [〜#〜] msdn [〜#〜] はクラスについて非常に静かなようです。 Googleの上位ヒット( ここ および ここ )は、Windowsフォームのディスパッチのみに合わせて調整されているようです。 Stephen Clearyは 記事 を書いています。これは、どのようなコンテキストが存在し、どのように機能するかを知るのにうれしいですが、実際にどこでいつ使用されるかについては理解できません。
実際にアクションを実行するが、SynchronizationContext.Current.Send/Postを使用してディスパッチされるタスクを取得するにはどうすればよいですか?
特別なタスクスケジューラを使用する:
Task.Factory.StartNew(
() => {}, // this will use current synchronization context
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
そして、誰でもSynchronizationContextの良い紹介をお勧めできますか
Stephen Clearyによる記事 It's All About the SynchronizationContext を見てください。
これを学んでいるとき、Task
TPLによって使用されるはTask
async /によって使用されるものとはかなり異なることを指摘することが重要です。 awaitですが、同じタイプです。たとえば、TPLは通常親/子タスクを使用しますが、async
/await
は使用しません。
TPLはタスクスケジューラを使用してタスクを実行します。デニスが指摘したように、TaskScheduler.FromCurrentSynchronizationContext
は、現在のPost
でSynchronizationContext
を使用してタスクを実行するタスクスケジューラを提供します。
async
/await
は通常、タスクスケジューラを使用しません。紹介情報 async
/await
post がブログにあり、コンテキスト情報が含まれています MSDN記事 でも簡単に説明しています(ただし、見落としがちです)。基本的に、async
メソッドがawait
で一時停止すると、デフォルトで現在のSynchronizationContext
がキャプチャされます(null
でない限り、この場合、現在のTaskScheduler
をキャプチャします)。 async
メソッドが再開すると、そのコンテキストでの実行が再開されます。
デニスは、現在のSynchronizationContext
にタスクをスケジュールするTPLの方法を指摘しましたが、async
/await
の世界では、そのようなアプローチは必要ありません。むしろ、Task.Run
を介してスレッドプールにタスクを明示的にスケジュールできます。
async Task MyMethodAsync()
{
// Whee, on a SynchronizationContext here!
await Task.Run(() => { }); // Ooo, on the thread pool!
// Back on the SynchronizationContext ...
// ... automagically!
}
SynchronizationContext
の記事を書いたのは、MSDNドキュメントが非常に不足していたためです。私は ブログの詳細情報 を持っていますが、重要なビットはすべてMSDNの記事にあります。多くのタイプは、AsyncOperation
を直接使用するのではなく、SynchronizationContext
を使用します。このための最良のドキュメントは EAPドキュメント(セクション「スレッド化とコンテキスト」)に埋め込まれています) です。ただし、async
/await
が原因でEAPが実質的に廃止されていることも指摘する必要があるため、AsyncOperation
(またはSynchronizationContext
)を使用してコードを記述しません。 -私が実際に自分で書くSynchronizationContext
でない限り。