我尝试查看使用以下代码生成许多任务时如何利用CPU:
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Console.WriteLine("Main Started");
MainChild(sw).Wait();
Console.WriteLine("Main ended: "+sw.Elapsed);
}
static async Task MainChild(Stopwatch sw)
{
Task[] tasks = new Task[100];
for (int i = 0; i < 100; i++)
{
tasks[i] = Task.Factory.StartNew(new Action(async()=> {
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
}
await Task.WhenAll(tasks);
}
我注意到,即使在执行任务之前,主线程也会执行:“ Main Ended:”。为什么会这样?
答案 0 :(得分:3)
Task.Factory.StartNew
方法已过时,如今doesn't understand async delegates也几乎从未使用过。
另一件事是Action
委托返回void,而async void
是一种即兴即忘的操作。此操作不会返回Task,也不会等待。
更改Action
:
tasks[i] = Task.Factory.StartNew(new Action(async () =>
{
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
致Func<Task>
和Task.Run
:
tasks[i] = Task.Run(new Func<Task>(async () =>
{
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
由于编译器可以推断出委托类型,因此我们可以将其缩短为:
tasks[i] = Task.Run(async () => ...
现在它可以按预期运行,并等待所有任务完成执行