如何启动并等待 Task 运行

Task.Run + Task.WhenAll

Task.Run 里边可以搭配 async,所有由 Task.Run 启动起来的 Task 所组成的数组允许被 WhenAll 等待,调用线程(如UI线程)不会阻塞

List<Task> taskArray = new List<Task>(3);

taskArray.Add(Task.Run(async() =>
{
    for (var i = 0; i < 3; i++)
    {
        Console.WriteLine("tom saying" + i.ToString());
        await Task.Delay(1500);
    }
}));
taskArray.Add(Task.Run(async() =>
{
    for (var i = 0; i < 3; i++)
    {
        Console.WriteLine("Ant saying" + i.ToString());
        await Task.Delay(1500);
    }
}));
taskArray.Add(Task.Run(async() =>
{
    for (var i = 0; i < 3; i++)
    {
        Console.WriteLine("Tour saying" + i.ToString());
        await Task.Delay(1500);
    }
}));

Task done = Task.WhenAll(taskArray.ToArray());
await done.ContinueWith((t) => { Console.WriteLine($"{t.Status}"); });
Console.WriteLine("All work done");

如果 done 换做 Wait() 来等待的话,就会阻塞调用线程,如果是 UI 线程运行 Wait() 的话界面将冻结

Task done = Task.WhenAll(taskArray.ToArray());
done.Wait();
Console.WriteLine("All work done");

Task.Factory.StartNew + Task.WaitAll();

如果用 StartNew() 的方法创建并启动 Task,想要获得等待效果方法不能有 async 修饰

List<Task> taskArray = new List<Task>(3);

taskArray.Add(Task.Factory.StartNew(() =>
{
    for (var i = 0; i < 30; i++)
    {
        Console.WriteLine("tom saying" + i.ToString());
        Task.Delay(1500);
    }
}));
taskArray.Add(Task.Factory.StartNew(() =>
{
    for (var i = 0; i < 30; i++)
    {
        Console.WriteLine("Ant saying" + i.ToString());
        Task.Delay(1500);
    }
}));
taskArray.Add(Task.Factory.StartNew(() =>
{
    for (var i = 0; i < 30; i++)
    {
        Console.WriteLine("Tour saying" + i.ToString());
        Task.Delay(1500);
    }
}));

Task.WaitAll(taskArray.ToArray());
Console.WriteLine("All work done");

注意 Task.Delay() 没有 await 的修饰,如果加入 await/async 的组合运行后 WaitAll() 将失效,这是为什么呢?不太懂。

posted @ 2020-02-21 17:30  试试手气  阅读(774)  评论(0编辑  收藏  举报