質問に文字通り答えるには、独自のTaskSchedulerを実装し、作成するすべてのタスクに割り当てることで、タスクの処理に使用するスレッドの数を制御できます。Microsoftには完全に機能する例さえあります。
ただし、根本的な問題に答えるために:Task
を意味するものではありませんThread
。実際、async / awaitの主な目標は、アプリのスレッド数を減らすことです。実際には、アプリ全体をasync / awaitとTasksを中心に設計し、単一のスレッドのみを使用する何千もの同時タスクを実行することが可能です。
コードをできるだけ少ないスレッドで実行する必要があります。理想的には、使用している論理CPUの数を超えないようにし、コードと同時にI/Oを実行する必要があります。OSは、追加のスレッドを作成することなく、すべてのI/Oを管理できます。タスクはこれを達成するのに役立ちます。
タスクごとのスレッドを作成できるのは、非同期性をエミュレートしている場合のみです。Task.Runを呼び出してブロッキングコードを実行します。この種のコードは確かに賢明ではありません。
Task t1 = Task.Run(()=>DownloadFile(url1));
Task t2 = Task.Run(()=>DownloadFile(url2));
await Task.WhenAll(t1, t2)
真の非同期コード(単一のスレッドで実行できる)ははるかに優れています。例:
Task t1 = DownloadFileAsync(url1);
Task t2 = DownloadFileAsync(url2);
await Task.WhenAll(t1, t2)
または、任意の数のタスクの場合:
List<Task> tasks = new List<Task>();
foreach(string url in urls)
{
tasks.Add(DownloadFileAsync(url))
}
await Task.WhenAll(tasks);