等待任务完成

6

我有两种简单的方法,我希望在它们完全完成之前不要继续进行进程。因此,我使用了await Task.WaitAll(tasks);但编译器在这一行给出了错误提示:

Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 1: cannot convert from ' 
'System.Collections.Generic.List<System.Threading.Tasks.Task>' to 
'System.Threading.Tasks.Task'   

为什么我要手动转换呢?我以为编译器会自动完成这个过程...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

internal class Program
{
    public static void Count1()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Count 1 " + i);
            Thread.Sleep(100);
        }
    }

    public static void Count2()
    {
        for (int i = 0; i < 20; i++)
        {
            Console.WriteLine("Count 2 " + i);
            Thread.Sleep(100);
        }
    }

    public static async Task Run()
    {
        List<Task> tasks = new List<Task>();

        Task t1 = Task.Run(()=>Count1());
        Task t2 = Task.Run(() => Count2());

        tasks.Add(t1);
        tasks.Add(t2);

        await Task.WaitAll(tasks);  //ERROR IS THROWN HERE
    }

    private static void Main(string[] args)
    {
        Run();

        Console.ReadKey();
    }
}

如果你真的需要WaitAll,你需要将列表转换为数组,像这样:Task.WaitAll(tasks.ToArray()); - Eliran Pe'er
Task[] tasks = new Task[] { t1, t2 }; Task.WaitAll(tasks); 工作正常。 - Lyrk
1
虽然这个方法可以工作,但它涉及在异步方法中进行阻塞,这通常是不好的做法。如果您将Run()方法设置为非异步方法,并使其返回void,那就没问题了... - Jon Skeet
2个回答

20

我猜你想使用WhenAll而不是WaitAllWaitAll是一个阻塞的调用,它在原始任务完成后同步返回所有结果。你不能等待该结果,因为它不是一个任务。

WhenAll是一个异步调用,它返回一个任务,在所有原始任务完成时完成。你可以等待它。

如果你把Run方法的结尾改成:

await Task.WhenAll(tasks);
Console.WriteLine("All tasks completed");

... 你将看到任务完成后的完成消息。


谢谢。WhenAll 起作用了。我不知道 WhenAll 返回一个 Task 对象。 - Lyrk

1
你可以将它用作:
Task.WaitAll(tasks.ToArray());
  • 需要Task参数,因此您需要使用linQ的toArray()。
  • 或者您也可以像@Jon Skeet建议的那样使用:Task.WhenAll(t1, t2);

Task.WaitAll和Task.WhenAll之间的主要区别在于前者将阻塞(类似于对单个任务使用Wait),而后者不会,并且可以等待,将控制权返回给调用方,直到所有任务完成。

更多细节:您可以在这里查看


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接