Task.waitALL 和Task.WhenALL有什么区别?如何使用
Task.WaitAll 和 Task.WhenAll 是两个不同的方法,它们都用于等待一组任务完成,但它们之间存在一些重要的区别。
Task.WaitAll
WaitAll 是一个同步方法,它会阻塞当前线程直到所有指定的任务完成。这意味着如果你在一个需要响应用户输入的线程上调用 WaitAll,那么这个线程将会停止响应,直到所有任务完成。因此,在 GUI 应用程序中不推荐在 UI 线程上使用 WaitAll。
使用示例
using System;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {
        var tasks = new Task[]
        {
            Task.Run(() => Task.Delay(1000)),
            Task.Run(() => Task.Delay(500))
        };
        try
        {
            // 这里会阻塞主线程直到所有任务完成
            Task.WaitAll(tasks);
            Console.WriteLine("All tasks completed.");
        }
        catch (AggregateException ex)
        {
            // 处理异常
            foreach (var innerEx in ex.InnerExceptions)
            {
                Console.WriteLine(innerEx.Message);
            }
        }
    }
}
Task.WhenAll
WhenAll 是一个异步方法,它不会阻塞调用线程,并且返回一个新的 Task<Task[]>,这个新任务在所有指定的任务完成后完成。你可以通过调用 Result 属性或使用 await 关键字来获取这些任务的结果或者等待它们完成。
使用示例
using System;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        var tasks = new Task[]
        {
            Task.Run(() => Task.Delay(1000)),
            Task.Run(() => Task.Delay(500))
        };
        try
        {
            // 这里不会阻塞主线程
            await Task.WhenAll(tasks);
            Console.WriteLine("All tasks completed.");
        }
        catch (AggregateException ex)
        {
            // 处理异常
            foreach (var innerEx in ex.InnerExceptions)
            {
                Console.WriteLine(innerEx.Message);
            }
        }
    }
}
总结
- 
Task.WaitAll: - 同步方法。
- 阻塞当前线程直到所有任务完成。
- 不适用于 UI 线程。
- 适合后台线程池线程或其他不需要立即响应的场景。
 
- 
Task.WhenAll: - 异步方法。
- 不会阻塞当前线程。
- 返回一个任务,该任务在所有指定的任务完成后完成。
- 可以安全地在 UI 线程中使用。
 
注意事项
- 
在使用 WaitAll或者WhenAll时,如果任何一个任务抛出了异常,那么这些异常会被封装到一个AggregateException中。你需要捕获并处理这个异常来获取内部的异常信息。
- 
在使用 WhenAll时,如果你在非异步上下文中使用它(即没有使用async和await),你可能需要等待它的完成,例如通过调用Result或者Wait方法。
- 
WhenAll返回一个Task<Task[]>类型的对象,你可以通过访问.Result来获取已完成的任务列表。
- 
如果你需要对每个任务单独进行操作,考虑使用 Task.WhenAny或者Task.WhenAll结合 LINQ 的Select方法。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号