TPL (TaskFactory.Startnew) は、スレッド プール内のスレッドの作業をキューに入れるという点で、ThreadPool.QueueUserWorkItem と同様に機能すると思います。
かなり。
私が読んだことから、 async/await は「時々」のみ新しいスレッドを作成するようです。
実際、決してそうではありません。マルチスレッドが必要な場合は、自分で実装する必要があります。Task.Run
の省略形である新しいメソッドがありTask.Factory.StartNew
、おそらくスレッド プールでタスクを開始する最も一般的な方法です。
IO 完了ポートを扱っていた場合、新しいスレッドを作成する必要がないことがわかりますが、それ以外の場合は作成する必要があると思います。
ビンゴ。そのため、 のようなメソッドStream.ReadAsync
は実際にTask
IOCP の周りにラッパーを作成します (IOCPStream
がある場合)。
非 I/O、非 CPU の「タスク」を作成することもできます。簡単な例はTask.Delay
で、一定時間後に完了するタスクを返します。
async
/の優れた点await
は、いくつかの作業をスレッド プールにキューイングし (例: Task.Run
)、I/O バウンド操作を実行し (例: Stream.ReadAsync
)、その他の操作を実行できることです (例: Task.Delay
)。すべてのタスク!それらは待機することも、 のように組み合わせて使用することもできますTask.WhenAll
。
返されるメソッドはすべてed にすることがTask
できますawait
- メソッドである必要はありませんasync
。そのTask.Delay
ため、I/O バウンド操作TaskCompletionSource
はタスクの作成と完了にのみ使用されます。スレッド プールで実行される唯一のことは、イベント発生時の実際のタスク完了 (タイムアウト、I/O 完了など) です。
FromCurrentSynchronizationContext の理解も常に少し曖昧だったと思います。本質的にはUIスレッドだといつも思っていました。
に記事を書きましたSynchronizationContext
。ほとんどの場合SynchronizationContext.Current
:
- 現在のスレッドが UI スレッドの場合、UI コンテキストです。
- 現在のスレッドが ASP.NET 要求を処理している場合、ASP.NET 要求コンテキストです。
- それ以外の場合は、スレッド プール コンテキストです。
どのスレッドも独自の を設定できるSynchronizationContext
ため、上記の規則には例外があります。
null でない場合、デフォルトのTask
awaiter はasync
現在のメソッドの残りをスケジュールすることに注意してください。それ以外の場合は、現在の状態になります。これは今日ではそれほど重要ではありませんが、近い将来、重要な違いになるでしょう。SynchronizationContext
TaskScheduler
私は自分のasync
/await
イントロを自分のブログに書きました。Stephen Toub は最近、優れたasync
/ await
FAQを投稿しました。
「同時実行」と「マルチスレッド」については、この関連する SO の質問を参照してください。async
マルチスレッド化されている場合とされていない場合があります。await Task.WhenAll
並列処理を使用または実行するのは簡単await Task.WhenAny
で、明示的にスレッド プール (Task.Run
または などConfigureAwait(false)
) を使用しない限り、複数の同時操作を同時に進行させることができます (たとえば、複数の I/O または のような他のタイプDelay
) -それらに必要なスレッドはありません。私はこの種のシナリオに対して「シングルスレッド同時実行」という用語を使用していますが、ASP.NET ホストでは、実際には「ゼロスレッド同時実行」になる可能性があります。これはかなり甘いです。