为何Task.WhenAll未等待所有异步任务执行完成?
问题分析与解决方案
你的问题出在Enumerable.Repeat的使用方式上:当你写Enumerable.Repeat(GeneratePostLike(...), numberOfLikesForPost)时,GeneratePostLike()会被立即调用一次,得到一个Task实例,然后Repeat只是将这个相同的Task实例重复numberOfLikesForPost次。最终Task.WhenAll等待的是同一个Task的多个引用,而非numberOfLikesForPost个独立的点赞任务,所以实际只执行了1次点赞操作,看起来像是提前进入后续流程。
修改后的代码
改用Enumerable.Range配合Select来生成独立的任务,确保每次迭代都调用GeneratePostLike创建新的Task:
var numberOfLikesForPost = random.Next(1, 100); var randomUsersForLikes = await userService.GetRandomUsers(numberOfLikesForPost); var generatePostLikeTasks = Enumerable.Range(0, numberOfLikesForPost) .Select(_ => GeneratePostLike( post.Id!, randomUsersForLikes.PickRandom().Id, cancellationToken )); await Task.WhenAll(generatePostLikeTasks);
额外说明
Enumerable.Range(0, numberOfLikesForPost)生成从0到numberOfLikesForPost-1的整数序列,确保有numberOfLikesForPost次迭代。- 每次迭代通过
Select调用GeneratePostLike,都会创建一个新的异步任务,所有任务会被并行执行,Task.WhenAll会等待所有任务完成后才继续后续流程。 - 如果需要避免同一个用户重复点赞同一篇帖子,可以在选择用户时做去重处理(比如先打乱用户列表再按顺序取,或者用HashSet记录已选用户ID),这和原for循环的逻辑保持一致即可。
内容的提问来源于stack exchange,提问作者napfernandes
相关产品推荐
相关产品推荐

