为什么 Task.WhenAll 不等待完成?

Kiw*_*nax 0 c# linq task task-parallel-library async-await

我在这里遇到了一个问题,你可能知道答案:我只是仍然无法弄清楚。

我在这里为一个简单的场景创建一个种子:为给定的帖子添加“喜欢”。方法签名是:

async Task GeneratePostLike(string postId, string userId, CancellationToken cancellationToken = default) {
    return await postLikeService.AddUserLikeToPost(
      new PostLikeInput { PostId = postId, UserId = userId },
      cancellationToken
    );
}
Run Code Online (Sandbox Code Playgroud)

我想随机生成对帖子的点赞。我正在使用随机和其他机制来获取随机数来执行此操作。

当我使用旧的 for 循环块时,它会按照我想要的方式执行。这是我正在使用的说明:

var numberOfLikesForPost = random.Next(1, 100);
var randomUsersForLikes = await userService.GetRandomUsers(numberOfLikesForPost);

for (var likeIndex = 0; likeIndex < numberOfLikesForPost; likeIndex++)
{
  var randomUserId = randomUsersForLikes.PickRandom().Id;
  await GeneratePostLike(post.Id!, randomUserId, cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,当我尝试使用 时Task.WhenAll,它只是执行一两次迭代并继续。看起来它的行为就像某种“一劳永逸”的行为。以下代码代表了我对Task.WhenAll块所做的事情:

var numberOfLikesForPost = random.Next(1, 100);
var randomUsersForLikes = await userService.GetRandomUsers(numberOfLikesForPost);

var generatePostLikeTasks = Enumerable.Repeat(
  GeneratePostLike(
    post.Id!,
    randomUsersForLikes.PickRandom().Id,
    cancellationToken
  ),
  numberOfLikesForPost
);

await Task.WhenAll(generatePostLikeTasks);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

您对我可以添加什么以使我的Task.WhenAll块在继续之前正确等待所有任务的执行有什么建议吗?

Ili*_*ian 5

var generatePostLikeTasks = Enumerable.Repeat(
  GeneratePostLike(
    post.Id!,
    randomUsersForLikes.PickRandom().Id,
    cancellationToken
  ),
  numberOfLikesForPost
);
Run Code Online (Sandbox Code Playgroud)

这不会创建numberOfLikesForPost多个任务,而只会numberOfLikesForPost多次重复相同的任务实例。

您应该能够将其更改为如下所示。尚未测试它,因为我目前无法访问 IDE。

var generatePostLikeTasks = Enumerable.Repeat(
  () => GeneratePostLike(
    post.Id!,
    randomUsersForLikes.PickRandom().Id,
    cancellationToken
  ),
  numberOfLikesForPost
).Select(f => f());
Run Code Online (Sandbox Code Playgroud)