任务.WhenAny ContinueWith:获取参数?

4
我想执行一系列任务,并在其中任何一个完成时执行同步操作,但我需要知道是哪个任务完成了。
请查看我的示例,并注意代码中的注释,在我不知道如何实现的几行之前。
public async Task<bool> GreetAsync(string name)
{
  if (name == null)
    return false;

  await InternalGreeter.GreetAsync(name);
  return true;
}

public async Task GreetAllAsync()
{
  var tasks = UserNames.Select(un => GreetAsync(un)).ToList();

  while(tasks.Any())
  {
    var finished = await Task.WhenAny(tasks);

    if(finished.Result)
    {
      //Here's what I'd like to achieve
      var username = finished.Arguments[0];
      WriteLine($"User {username} has been greeted.");
    }

    tasks.Remove(finished);
  } 
}

根据示例。

在我的真实场景中,我有一个客户列表,我必须逐一遍历它们并更新远程服务器上的信用状态(远程服务器不支持批量更新)。 在每个客户更新完成后,我必须在数据库中标记该客户已获得认证。


1
那么,你有什么问题? - Stephen Cleary
你做了什么,发生了什么事? - Kevin Avignon
我认为你不应该这样做。为什么不直接使用 UserNames.Select(un => GreetAsync(un)).ContinueWith(...).ToList(); - DavidG
Task有一个AsyncState属性,它代表着状态对象,作为第二个参数传递给Task构造函数或ContinueWith,但你没有使用任何一个。 - Collin Dauphinee
2个回答

6

你几乎从不想像那样一次处理一个任务列表,等它们完成。相反,只需引入一个更高级别的操作,并将Task.WhenAny改写为Task.WhenAll来等待这些更高级别的操作。

public async Task<bool> GreetAsync(string name)
{
  if (name == null)
    return false;

  await InternalGreeter.GreetAsync(name);
  return true;
}

private async Task<bool> GreetAndReportGreetedAsync(string name)
{
  var result = await GreetAsync(name);
  WriteLine($"User {name} has been greeted.");
  return result;
}

public async Task GreetAllAsync()
{
  await Task.WhenAll(UserNames.Select(un => GreetAsync(un));
}

“GreetAndGreetAsync” 可以是一个 lambda 表达式吗?或者有没有更好的方法不需要一个专门的方法?顺便说一下,我已经更新了我的问题。 - Shimmy Weitzhandler
1
@Shimmy:当然,任何方法都可以是lambda表达式。我不认为这是“更好的”,但如果你喜欢它:await Task.WhenAll(UserNames.Select(async un => { if (await GreetAsync(un)) WriteLine($"User {un} has been greeted."); })); - Stephen Cleary

-1

为什么不直接使用ContinueWith呢?像这样:

public async Task GreetAllAsync(List<string> UserNames)
{
  var tasks = UserNames
    .Select(un => GreetAsync(un)
        .ContinueWith(x => {
            Console.WriteLine(un + " has been greeted");
        }));

    await Task.WhenAll(tasks);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接