在for循环中生成任务

时间:2018-09-06 09:24:08

标签: c# async-await task

我尝试查看使用以下代码生成许多任务时如何利用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:”。为什么会这样?

1 个答案:

答案 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 () => ...

现在它可以按预期运行,并等待所有任务完成执行