如何构建含两个匿名函数任务的异步方法?附Task.WhenAll并行伪代码
如何编写并行执行两个匿名函数任务的异步方法?
嘿,这个问题我熟!要实现两个匿名函数任务并行执行、等待全部完成后再继续的异步方法,核心就是利用Task.WhenAll来协调多个任务,同时结合异步方法的基本规范。下面我一步步拆解结构,再附上实用的伪代码示例。
核心结构要点
首先,你得记住异步方法的几个基础规则:
- 方法必须标记为
async - 返回类型要么是
Task(无返回值),要么是Task<T>(需要返回结果时) - 用
await关键字等待任务完成,避免阻塞线程
对于并行执行两个匿名任务,关键步骤是:
- 把两个匿名函数分别包装成
Task实例(如果是异步逻辑,用async lambda) - 用
Task.WhenAll一次性等待所有任务完成 - 等所有任务结束后,再执行后续逻辑或返回结果
伪代码示例
示例1:无返回值的并行任务
如果你的两个任务不需要返回结果,只是执行异步操作,代码大概是这样:
// 异步方法,无返回值,标记为async并返回Task public async Task ExecuteTwoParallelTasksAsync() { // 第一个匿名异步任务:用Task.Run包装async lambda var task1 = Task.Run(async () => { // 这里写第一个任务的逻辑,比如调用异步API、IO操作 await FetchDataFromApiAsync("https://api.example.com/data1"); Console.WriteLine("第一个任务执行完成"); }); // 第二个匿名异步任务 var task2 = Task.Run(async () => { // 第二个任务的逻辑,比如处理本地文件 await ProcessLocalFileAsync("path/to/file.txt"); Console.WriteLine("第二个任务执行完成"); }); // 等待两个任务全部完成,才继续往下走 await Task.WhenAll(task1, task2); // 所有任务完成后执行的后续逻辑 Console.WriteLine("两个任务都搞定啦!现在继续执行后续代码"); }
示例2:带返回值的并行任务
如果两个任务需要返回结果,最后要合并结果再返回,那可以这样写:
// 异步方法,返回Task<int>表示最终返回一个整数结果 public async Task<int> GetCombinedResultFromTasksAsync() { // 第一个返回整数的匿名任务 var task1 = Task.Run(async () => { await Task.Delay(1000); // 模拟耗时异步操作 return 20; // 任务1的返回值 }); // 第二个返回整数的匿名任务 var task2 = Task.Run(async () => { await Task.Delay(1500); // 模拟更长的异步操作 return 30; // 任务2的返回值 }); // 等待所有任务完成,同时获取所有结果(结果数组的顺序和传入任务的顺序一致) int[] taskResults = await Task.WhenAll(task1, task2); // 处理结果,比如求和 int total = taskResults[0] + taskResults[1]; // 返回最终合并后的结果 return total; }
示例3:带异常处理的版本
实际开发中难免遇到任务失败的情况,记得给Task.WhenAll加上异常处理:
public async Task ExecuteTasksWithErrorHandlingAsync() { var task1 = Task.Run(async () => { await Task.Delay(500); throw new InvalidOperationException("任务1执行失败了"); }); var task2 = Task.Run(async () => { await Task.Delay(1000); Console.WriteLine("任务2执行成功"); }); try { // 等待所有任务完成,如果有任务抛出异常,这里会触发AggregateException await Task.WhenAll(task1, task2); } catch (AggregateException ex) { // 遍历所有内部异常,逐个处理 foreach (var innerException in ex.InnerExceptions) { Console.WriteLine($"捕获到异常:{innerException.Message}"); } } // 即使有任务失败,后续逻辑依然可以执行 Console.WriteLine("异常处理完成,继续执行后续代码"); }
额外小提示
- 如果你的任务是IO绑定的(比如调用API、读写文件),其实不需要用
Task.Run,直接写async lambda就行,因为IO操作本身不会占用线程:var task1 = async () => await FetchDataFromApiAsync("url1"); await Task.WhenAll(task1(), task2()); // 注意要调用lambda得到Task实例 Task.WhenAll会等待所有任务完成,不管任务执行的快慢,只要全部结束才会继续。如果需要等待任意一个任务完成,可以用Task.WhenAny,不过这是另一个场景啦。
内容的提问来源于stack exchange,提问作者StackMan
相关产品推荐
相关产品推荐

